396 lines
14 KiB
C++
396 lines
14 KiB
C++
|
#include "mainwindow.h"
|
||
|
#include "./ui_mainwindow.h"
|
||
|
#include <QTableWidget>
|
||
|
#include <QVBoxLayout>
|
||
|
#include <QTabWidget>
|
||
|
#include <QGroupBox>
|
||
|
#include <QLabel>
|
||
|
#include <QGridLayout>
|
||
|
#include <QLineEdit>
|
||
|
#include <QPushButton>
|
||
|
#include <QFileDialog>
|
||
|
#include <QHeaderView>
|
||
|
#include <QMessageBox>
|
||
|
#include <QProcess>
|
||
|
#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<QTableWidget *>("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<QTableWidget *>("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<QTableWidget *>("table1");
|
||
|
QTableWidget *table2 = findChild<QTableWidget *>("table2");
|
||
|
table1->clear();
|
||
|
table2->clear();
|
||
|
table1->setRowCount(0);
|
||
|
table2->setRowCount(0);
|
||
|
centralWidget()->setEnabled(false);
|
||
|
}
|
||
|
|
||
|
void MainWindow::generate()
|
||
|
{
|
||
|
QLineEdit *modelNameLineEdit = findChild<QLineEdit *>("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<QLineEdit *>("firstNamespaceLineEdit");
|
||
|
QLineEdit *secondNamespaceLineEdit = findChild<QLineEdit *>("secondNamespaceLineEdit");
|
||
|
QLineEdit *thirdNamespaceLineEdit = findChild<QLineEdit *>("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<QTableWidget *>("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<QTableWidget *>("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";
|
||
|
}
|