diff --git a/Uft30ChangeCode.pro b/Uft30ChangeCode.pro index 087a85d..46573c6 100644 --- a/Uft30ChangeCode.pro +++ b/Uft30ChangeCode.pro @@ -15,6 +15,7 @@ SOURCES += main.cpp \ src/pages/functionsearch/uft3functionsearchpage.cpp \ src/pages/help/helppage.cpp \ src/pages/settings/settingspage.cpp \ + src/pages/metadatupdate/metadatupdatepage.cpp \ src/utils/datacache.cpp \ src/utils/uf2configreader.cpp \ src/utils/uft3configreader.cpp \ @@ -29,6 +30,7 @@ HEADERS += src/mainwindow/mainwindow.h \ src/pages/functionsearch/uft3functionsearchpage.h \ src/pages/help/helppage.h \ src/pages/settings/settingspage.h \ + src/pages/metadatupdate/metadatupdatepage.h \ src/utils/datacache.h \ src/utils/uf2configreader.h \ src/utils/uft3configreader.h \ diff --git a/resources.qrc b/resources.qrc index 8fc6235..4dc47a1 100644 --- a/resources.qrc +++ b/resources.qrc @@ -6,5 +6,6 @@ resources/images/zhedie_right.png resources/images/max.png resources/images/min.png + resources/images/update.png \ No newline at end of file diff --git a/resources/images/update.png b/resources/images/update.png new file mode 100644 index 0000000..def993c Binary files /dev/null and b/resources/images/update.png differ diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp index 2c43bfb..0994fe2 100644 --- a/src/mainwindow/mainwindow.cpp +++ b/src/mainwindow/mainwindow.cpp @@ -50,18 +50,12 @@ MainWindow::MainWindow(QWidget *parent) QFileInfo exeInfo(exePath); if (!exeInfo.exists() || !exeInfo.isFile()) { - LogManager::instance()->logWarning("⚠️ 警告:未找到 uf2touft3/uf2touft3.exe!"); - LogManager::instance()->log(QString(" 期望位置:%1").arg(exePath)); - } else { - LogManager::instance()->log("✓ Python 工具准备就绪"); + LogManager::instance()->logError(QString("未找到转换工具: %1").arg(exePath)); } connect(m_pythonRunner, &PythonRunner::finished, this, &MainWindow::onPythonRunnerFinished); connect(m_pythonRunner, &PythonRunner::standardOutput, this, &MainWindow::onPythonRunnerOutput); connect(m_pythonRunner, &PythonRunner::standardError, this, &MainWindow::onPythonRunnerError); - connect(m_pythonRunner, &PythonRunner::started, []() { - LogManager::instance()->log("转换任务已启动..."); - }); QTimer::singleShot(100, this, &MainWindow::updateNavigationButtonIcon); } @@ -125,19 +119,21 @@ void MainWindow::initContent() QString settingKey; QString funcSearchKey; QString funcConvertKey; + QString metadataKey; addExpanderNode("功能转码", funcConvertKey, ElaIconType::FileCode); addPageNode("业务转码", createBatchConvertPage(), funcConvertKey, ElaIconType::ArrowsRepeat); addExpanderNode("功能查询", funcSearchKey, ElaIconType::MagnifyingGlass); - addPageNode("UF20功能查询", createUF20FunctionSearchPage(), funcSearchKey, ElaIconType::FileCode); - addPageNode("UFT3功能查询", createUFT3FunctionSearchPage(), funcSearchKey, ElaIconType::FileCode); + addPageNode("UF20功能查询", createUF20FunctionSearchPage(), funcSearchKey, ElaIconType::MagnifyingGlassPlus); + addPageNode("UFT3功能查询", createUFT3FunctionSearchPage(), funcSearchKey, ElaIconType::MagnifyingGlassPlus); + expandNavigationNode(funcConvertKey); + + addPageNode("元数据更新", createMetadataUpdatePage(), ElaIconType::ArrowsRotate); addFooterNode("帮助", createHelpPage(), helpKey, 0, ElaIconType::CircleQuestion); - addFooterNode("关于", createAboutPage(), aboutKey, 0, ElaIconType::User); + addFooterNode("关于", createAboutPage(), aboutKey, 0, ElaIconType::Info); addFooterNode("设置", createSettingsPage(), settingKey, 0, ElaIconType::GearComplex); - - expandNavigationNode(funcConvertKey); } QWidget* MainWindow::createBatchConvertPage() @@ -155,7 +151,10 @@ QWidget* MainWindow::createFunctionSearchPage() QWidget* MainWindow::createUF20FunctionSearchPage() { - return new UF20FunctionSearchPage; + UF20FunctionSearchPage *page = new UF20FunctionSearchPage; + connect(page, &UF20FunctionSearchPage::addFunctionToConvert, + m_batchConvertPage, &BatchConvertPage::addFunction); + return page; } QWidget* MainWindow::createUFT3FunctionSearchPage() @@ -178,6 +177,11 @@ QWidget* MainWindow::createSettingsPage() return new SettingsPage(); } +QWidget* MainWindow::createMetadataUpdatePage() +{ + return new MetadataUpdatePage(); +} + void MainWindow::onBatchConvertStart() { if (m_pythonRunner->isRunning()) { diff --git a/src/mainwindow/mainwindow.h b/src/mainwindow/mainwindow.h index 1db02fb..95f7c5f 100644 --- a/src/mainwindow/mainwindow.h +++ b/src/mainwindow/mainwindow.h @@ -12,6 +12,7 @@ #include "src/pages/help/helppage.h" #include "src/pages/about/aboutpage.h" #include "src/pages/settings/settingspage.h" +#include "src/pages/metadatupdate/metadatupdatepage.h" class MainWindow : public ElaWindow { @@ -32,6 +33,7 @@ private: QWidget* createHelpPage(); QWidget* createAboutPage(); QWidget* createSettingsPage(); + QWidget* createMetadataUpdatePage(); void loadConfigCache(); diff --git a/src/pages/batchconvert/batchconvertpage.cpp b/src/pages/batchconvert/batchconvertpage.cpp index 5342d5b..d4656a5 100644 --- a/src/pages/batchconvert/batchconvertpage.cpp +++ b/src/pages/batchconvert/batchconvertpage.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -14,11 +13,13 @@ #include #include #include "src/utils/logmanager.h" +#include "ElaPushButton.h" BatchConvertPage::BatchConvertPage(QWidget *parent) : QWidget(parent) { initUI(); + loadFromCustJson(); } BatchConvertPage::~BatchConvertPage() @@ -48,14 +49,11 @@ void BatchConvertPage::initUI() funcLayout->addWidget(m_funcTable); QHBoxLayout *tableBtnLayout = new QHBoxLayout; - QPushButton *addBtn = new QPushButton("添加"); - addBtn->setStyleSheet("padding: 6px 20px;"); + ElaPushButton *addBtn = new ElaPushButton("添加"); connect(addBtn, &QPushButton::clicked, this, &BatchConvertPage::onAddFunction); - QPushButton *removeBtn = new QPushButton("删除选中"); - removeBtn->setStyleSheet("padding: 6px 15px;"); + ElaPushButton *removeBtn = new ElaPushButton("删除选中"); connect(removeBtn, &QPushButton::clicked, this, &BatchConvertPage::onRemoveFunction); - QPushButton *clearBtn = new QPushButton("清空列表"); - clearBtn->setStyleSheet("padding: 6px 15px;"); + ElaPushButton *clearBtn = new ElaPushButton("清空列表"); connect(clearBtn, &QPushButton::clicked, this, &BatchConvertPage::onClearTable); tableBtnLayout->addWidget(addBtn); tableBtnLayout->addStretch(); @@ -99,8 +97,7 @@ void BatchConvertPage::initUI() layout->addWidget(progressBox); QHBoxLayout *btnLayout = new QHBoxLayout; - m_startBtn = new QPushButton("开始转换"); - m_startBtn->setStyleSheet("background-color: #1abc9c; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;"); + m_startBtn = new ElaPushButton("开始转换"); connect(m_startBtn, &QPushButton::clicked, this, &BatchConvertPage::onStartConvert); btnLayout->addStretch(); btnLayout->addWidget(m_startBtn); @@ -323,18 +320,18 @@ void BatchConvertPage::onClearTable() bool BatchConvertPage::saveToCustJson(const QStringList &funcList) { QString jsonPath = QCoreApplication::applicationDirPath() + "/uf2touft3/cust.json"; - + QFile file(jsonPath); if (!file.open(QIODevice::ReadOnly)) { LogManager::instance()->logError(QString("无法打开文件: %1").arg(jsonPath)); return false; } - + QByteArray data = file.readAll(); file.close(); - + QString content = QString::fromUtf8(data); - + int dirStart = content.indexOf("\"dir\":["); if (dirStart < 0) { dirStart = content.indexOf("\"dir\" : ["); @@ -343,7 +340,7 @@ bool BatchConvertPage::saveToCustJson(const QStringList &funcList) LogManager::instance()->logError("未找到 \"dir\" 节点"); return false; } - + int arrayStart = content.indexOf('[', dirStart); int bracketCount = 1; int pos = arrayStart + 1; @@ -353,27 +350,90 @@ bool BatchConvertPage::saveToCustJson(const QStringList &funcList) pos++; } int arrayEnd = pos; - + QString newDirArray = "["; for (int i = 0; i < funcList.size(); ++i) { if (i > 0) newDirArray += ","; newDirArray += "\n \"" + funcList[i] + ".service_design\""; } newDirArray += "\n ]"; - + content.replace(arrayStart, arrayEnd - arrayStart, newDirArray); - + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { LogManager::instance()->logError(QString("无法写入文件: %1").arg(jsonPath)); return false; } - + file.write(content.toUtf8()); file.close(); - + return true; } +void BatchConvertPage::loadFromCustJson() +{ + QString jsonPath = QCoreApplication::applicationDirPath() + "/uf2touft3/cust.json"; + + QFile file(jsonPath); + if (!file.open(QIODevice::ReadOnly)) { + return; + } + + QByteArray data = file.readAll(); + file.close(); + + QString content = QString::fromUtf8(data); + + int convertStart = content.indexOf("\"convert\":"); + if (convertStart < 0) { + convertStart = content.indexOf("\"convert\" :"); + } + if (convertStart < 0) { + return; + } + + int arrayStart = content.indexOf('[', convertStart); + int bracketCount = 1; + int pos = arrayStart + 1; + while (pos < content.length() && bracketCount > 0) { + if (content[pos] == '[') bracketCount++; + else if (content[pos] == ']') bracketCount--; + pos++; + } + int arrayEnd = pos; + + QString arrayContent = content.mid(arrayStart + 1, arrayEnd - arrayStart - 1).trimmed(); + + if (arrayContent.isEmpty() || arrayContent == "null") { + return; + } + + QStringList items; + int itemPos = 0; + while (itemPos < arrayContent.length()) { + int itemStart = arrayContent.indexOf('"', itemPos); + if (itemStart < 0) break; + + int itemEnd = arrayContent.indexOf('"', itemStart + 1); + if (itemEnd < 0) break; + + QString item = arrayContent.mid(itemStart + 1, itemEnd - itemStart - 1); + items.append(item); + + itemPos = itemEnd + 1; + } + + for (QString &item : items) { + if (item.endsWith(".service_design")) { + item = item.left(item.length() - static_cast(strlen(".service_design"))); + } + } + + m_funcList = items; + updateTable(); +} + void BatchConvertPage::onStartConvert() { if (m_startBtn->text() == "停止转换") { @@ -427,3 +487,24 @@ void BatchConvertPage::onConvertFinished() m_startBtn->setText("开始转换"); m_startBtn->setStyleSheet("background-color: #1abc9c; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;"); } + +void BatchConvertPage::addFunction(const QString &funcName) +{ + if (funcName.isEmpty()) { + return; + } + + if (m_funcList.contains(funcName)) { + QMessageBox::information(nullptr, "提示", QString("功能 [%1] 已在列表中").arg(funcName)); + return; + } + + m_funcList.append(funcName); + updateTable(); + + if (saveToCustJson(m_funcList)) { + QMessageBox::information(nullptr, "提示", QString("已将功能 [%1] 添加到业务转码").arg(funcName)); + } else { + QMessageBox::warning(nullptr, "警告", "添加到业务转码成功,但保存到 cust.json 失败"); + } +} diff --git a/src/pages/batchconvert/batchconvertpage.h b/src/pages/batchconvert/batchconvertpage.h index e48dfba..68fd23b 100644 --- a/src/pages/batchconvert/batchconvertpage.h +++ b/src/pages/batchconvert/batchconvertpage.h @@ -2,11 +2,11 @@ #define BATCHCONVERTPAGE_H #include -#include #include -#include #include #include +#include "ElaLineEdit.h" +#include "ElaPushButton.h" class BatchConvertPage : public QWidget { @@ -24,6 +24,7 @@ public slots: void onProgressUpdate(int progress, const QString& status); void onConvertFinished(); void onConvertStarted(); + void addFunction(const QString &funcName); int getFunctionCount() const { return m_funcList.size(); } QStringList getFunctionList() const { return m_funcList; } @@ -38,6 +39,7 @@ private slots: private: void initUI(); bool saveToCustJson(const QStringList &funcList); + void loadFromCustJson(); bool checkFunctionExists(const QString &funcName); void updateTable(); void resizeEvent(QResizeEvent *event) override; @@ -46,7 +48,7 @@ private: QStringList m_funcList; QProgressBar *m_progressBar; QLabel *m_progressLabel; - QPushButton *m_startBtn; + ElaPushButton *m_startBtn; }; #endif diff --git a/src/pages/functionsearch/functionsearchpage.h b/src/pages/functionsearch/functionsearchpage.h index de85f47..24e9f1f 100644 --- a/src/pages/functionsearch/functionsearchpage.h +++ b/src/pages/functionsearch/functionsearchpage.h @@ -2,9 +2,9 @@ #define FUNCTIONSEARCHPAGE_H #include -#include #include -#include +#include "ElaLineEdit.h" +#include "ElaPushButton.h" class FunctionSearchPage : public QWidget { @@ -17,7 +17,7 @@ public: private: void initUI(); - QLineEdit *m_searchEdit; + ElaLineEdit *m_searchEdit; QTableWidget *m_resultTable; }; diff --git a/src/pages/functionsearch/uf20functionsearchpage.cpp b/src/pages/functionsearch/uf20functionsearchpage.cpp index 40e41e8..a61ba49 100644 --- a/src/pages/functionsearch/uf20functionsearchpage.cpp +++ b/src/pages/functionsearch/uf20functionsearchpage.cpp @@ -6,7 +6,10 @@ #include #include #include -#include +#include "ElaComboBox.h" +#include "ElaLineEdit.h" +#include "ElaPushButton.h" +#include "ElaText.h" UF20FunctionSearchPage::UF20FunctionSearchPage(QWidget *parent) : QWidget(parent) @@ -27,18 +30,17 @@ void UF20FunctionSearchPage::initUI() QHBoxLayout *searchLayout = new QHBoxLayout; searchLayout->setSpacing(10); - m_searchComboBox = new QComboBox; + m_searchComboBox = new ElaComboBox; m_searchComboBox->addItem("功能名称", "cname"); m_searchComboBox->addItem("功能编号", "function_no"); searchLayout->addWidget(m_searchComboBox); - m_searchEdit = new QLineEdit; + m_searchEdit = new ElaLineEdit; m_searchEdit->setPlaceholderText("输入查询内容"); m_searchEdit->setMinimumWidth(300); searchLayout->addWidget(m_searchEdit); - QPushButton *searchBtn = new QPushButton("搜索"); - searchBtn->setStyleSheet("background-color: #3498db; color: white; padding: 6px 20px; border: none; border-radius: 4px;"); + ElaPushButton *searchBtn = new ElaPushButton("搜索"); connect(searchBtn, &QPushButton::clicked, this, &UF20FunctionSearchPage::onSearch); searchLayout->addWidget(searchBtn); @@ -47,12 +49,21 @@ void UF20FunctionSearchPage::initUI() m_resultTable = new QTableWidget; m_resultTable->setColumnCount(3); - m_resultTable->setHorizontalHeaderLabels({"英文名", "功能编号", "功能名称"}); + m_resultTable->setHorizontalHeaderLabels({"功能名称", "英文名", "功能编号"}); m_resultTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_resultTable->setMinimumHeight(400); m_resultTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_resultTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_resultTable->setSelectionMode(QAbstractItemView::SingleSelection); + connect(m_resultTable, &QTableWidget::cellDoubleClicked, this, &UF20FunctionSearchPage::onTableDoubleClicked); layout->addWidget(m_resultTable); + + QHBoxLayout *tipLayout = new QHBoxLayout; + QLabel *tipLabel = new QLabel("💡 双击选中行添加转码业务"); + tipLabel->setStyleSheet("color: #666; font-size: 13px;"); + tipLayout->addWidget(tipLabel); + tipLayout->addStretch(); + layout->addLayout(tipLayout); } void UF20FunctionSearchPage::onSearch() @@ -93,3 +104,12 @@ void UF20FunctionSearchPage::onSearch() row++; } } + +void UF20FunctionSearchPage::onTableDoubleClicked(int row, int column) +{ + QTableWidgetItem *item = m_resultTable->item(row, 0); + if (item) { + QString funcName = item->text(); + emit addFunctionToConvert(funcName); + } +} diff --git a/src/pages/functionsearch/uf20functionsearchpage.h b/src/pages/functionsearch/uf20functionsearchpage.h index bfeb318..ca8de33 100644 --- a/src/pages/functionsearch/uf20functionsearchpage.h +++ b/src/pages/functionsearch/uf20functionsearchpage.h @@ -2,10 +2,10 @@ #define UF20FUNCTIONSEARCHPAGE_H #include -#include #include -#include -#include +#include "ElaComboBox.h" +#include "ElaLineEdit.h" +#include "ElaPushButton.h" class UF20FunctionSearchPage : public QWidget { @@ -15,14 +15,18 @@ public: explicit UF20FunctionSearchPage(QWidget *parent = nullptr); ~UF20FunctionSearchPage(); +signals: + void addFunctionToConvert(const QString &funcName); + private slots: void onSearch(); + void onTableDoubleClicked(int row, int column); private: void initUI(); - QComboBox *m_searchComboBox; - QLineEdit *m_searchEdit; + ElaComboBox *m_searchComboBox; + ElaLineEdit *m_searchEdit; QTableWidget *m_resultTable; }; diff --git a/src/pages/functionsearch/uft3functionsearchpage.cpp b/src/pages/functionsearch/uft3functionsearchpage.cpp index 86945d4..c457c7e 100644 --- a/src/pages/functionsearch/uft3functionsearchpage.cpp +++ b/src/pages/functionsearch/uft3functionsearchpage.cpp @@ -6,7 +6,9 @@ #include #include #include -#include +#include "ElaComboBox.h" +#include "ElaLineEdit.h" +#include "ElaPushButton.h" UFT3FunctionSearchPage::UFT3FunctionSearchPage(QWidget *parent) : QWidget(parent) @@ -27,18 +29,17 @@ void UFT3FunctionSearchPage::initUI() QHBoxLayout *searchLayout = new QHBoxLayout; searchLayout->setSpacing(10); - m_searchComboBox = new QComboBox; + m_searchComboBox = new ElaComboBox; m_searchComboBox->addItem("功能名称", "cname"); m_searchComboBox->addItem("功能编号", "function_no"); searchLayout->addWidget(m_searchComboBox); - m_searchEdit = new QLineEdit; + m_searchEdit = new ElaLineEdit; m_searchEdit->setPlaceholderText("输入查询内容"); m_searchEdit->setMinimumWidth(300); searchLayout->addWidget(m_searchEdit); - QPushButton *searchBtn = new QPushButton("搜索"); - searchBtn->setStyleSheet("background-color: #3498db; color: white; padding: 6px 20px; border: none; border-radius: 4px;"); + ElaPushButton *searchBtn = new ElaPushButton("搜索"); connect(searchBtn, &QPushButton::clicked, this, &UFT3FunctionSearchPage::onSearch); searchLayout->addWidget(searchBtn); diff --git a/src/pages/functionsearch/uft3functionsearchpage.h b/src/pages/functionsearch/uft3functionsearchpage.h index 79075c8..2a14d02 100644 --- a/src/pages/functionsearch/uft3functionsearchpage.h +++ b/src/pages/functionsearch/uft3functionsearchpage.h @@ -2,10 +2,10 @@ #define UFT3FUNCTIONSEARCHPAGE_H #include -#include #include -#include -#include +#include "ElaComboBox.h" +#include "ElaLineEdit.h" +#include "ElaPushButton.h" class UFT3FunctionSearchPage : public QWidget { @@ -21,8 +21,8 @@ private slots: private: void initUI(); - QComboBox *m_searchComboBox; - QLineEdit *m_searchEdit; + ElaComboBox *m_searchComboBox; + ElaLineEdit *m_searchEdit; QTableWidget *m_resultTable; }; diff --git a/src/pages/metadatupdate/metadatupdatepage.cpp b/src/pages/metadatupdate/metadatupdatepage.cpp new file mode 100644 index 0000000..17742b0 --- /dev/null +++ b/src/pages/metadatupdate/metadatupdatepage.cpp @@ -0,0 +1,188 @@ +#include "metadatupdatepage.h" +#include +#include +#include +#include +#include + +MetadataUpdatePage::MetadataUpdatePage(QWidget *parent) + : QWidget(parent) +{ + initUI(); +} + +MetadataUpdatePage::~MetadataUpdatePage() +{ +} + +void MetadataUpdatePage::initUI() +{ + QHBoxLayout *mainLayout = new QHBoxLayout(this); + mainLayout->setContentsMargins(50, 50, 50, 50); + mainLayout->setSpacing(60); + + // ========================================== + // UFT3更新范围 + // ========================================== + QVBoxLayout *uft3SectionLayout = new QVBoxLayout; + uft3SectionLayout->setSpacing(15); + + QGroupBox *uft3Group = new QGroupBox("UFT3更新范围"); + QGridLayout *uft3Grid = new QGridLayout(uft3Group); + uft3Grid->setSpacing(15); + uft3Grid->setContentsMargins(15, 15, 15, 15); + + m_uft3StdField = new ElaCheckBox("标准字段"); + m_uft3StdField->setChecked(true); + uft3Grid->addWidget(m_uft3StdField, 0, 0); + + m_uft3DataType = new ElaCheckBox("数据类型"); + m_uft3DataType->setChecked(true); + uft3Grid->addWidget(m_uft3DataType, 0, 1); + + m_uft3ErrorNo = new ElaCheckBox("标准错误号"); + m_uft3ErrorNo->setChecked(true); + uft3Grid->addWidget(m_uft3ErrorNo, 1, 0); + + m_uft3Interface = new ElaCheckBox("接口数据"); + m_uft3Interface->setChecked(true); + uft3Grid->addWidget(m_uft3Interface, 1, 1); + + uft3SectionLayout->addWidget(uft3Group); + + QHBoxLayout *uft3BtnLayout = new QHBoxLayout; + uft3BtnLayout->setSpacing(15); + ElaPushButton *uft3SelectAllBtn = new ElaPushButton("全选"); + connect(uft3SelectAllBtn, &QPushButton::clicked, this, &MetadataUpdatePage::onUFT3SelectAll); + ElaPushButton *uft3SelectNoneBtn = new ElaPushButton("全不选"); + connect(uft3SelectNoneBtn, &QPushButton::clicked, this, &MetadataUpdatePage::onUFT3SelectNone); + ElaPushButton *uft3UpdateBtn = new ElaPushButton("更新UFT3"); + connect(uft3UpdateBtn, &QPushButton::clicked, this, &MetadataUpdatePage::onUpdateUFT3); + + uft3BtnLayout->addStretch(); + uft3BtnLayout->addWidget(uft3SelectAllBtn); + uft3BtnLayout->addWidget(uft3SelectNoneBtn); + uft3BtnLayout->addWidget(uft3UpdateBtn); + uft3BtnLayout->addStretch(); + + uft3SectionLayout->addLayout(uft3BtnLayout); + mainLayout->addLayout(uft3SectionLayout); + + // ========================================== + // UF20更新范围 + // ========================================== + QVBoxLayout *uf20SectionLayout = new QVBoxLayout; + uf20SectionLayout->setSpacing(15); + + QGroupBox *uf20Group = new QGroupBox("UF20更新范围"); + QGridLayout *uf20Grid = new QGridLayout(uf20Group); + uf20Grid->setSpacing(15); + uf20Grid->setContentsMargins(15, 15, 15, 15); + + m_uf20StdField = new ElaCheckBox("标准字段"); + m_uf20StdField->setChecked(true); + uf20Grid->addWidget(m_uf20StdField, 0, 0); + + m_uf20DataType = new ElaCheckBox("数据类型"); + m_uf20DataType->setChecked(true); + uf20Grid->addWidget(m_uf20DataType, 0, 1); + + m_uf20ErrorNo = new ElaCheckBox("标准错误号"); + m_uf20ErrorNo->setChecked(true); + uf20Grid->addWidget(m_uf20ErrorNo, 1, 0); + + m_uf20Table = new ElaCheckBox("表结构"); + m_uf20Table->setChecked(true); + uf20Grid->addWidget(m_uf20Table, 1, 1); + + m_uf20Interface = new ElaCheckBox("接口数据"); + m_uf20Interface->setChecked(true); + uf20Grid->addWidget(m_uf20Interface, 2, 0); + + uf20SectionLayout->addWidget(uf20Group); + + QHBoxLayout *uf20BtnLayout = new QHBoxLayout; + uf20BtnLayout->setSpacing(15); + ElaPushButton *uf20SelectAllBtn = new ElaPushButton("全选"); + connect(uf20SelectAllBtn, &QPushButton::clicked, this, &MetadataUpdatePage::onUF20SelectAll); + ElaPushButton *uf20SelectNoneBtn = new ElaPushButton("全不选"); + connect(uf20SelectNoneBtn, &QPushButton::clicked, this, &MetadataUpdatePage::onUF20SelectNone); + ElaPushButton *uf20UpdateBtn = new ElaPushButton("更新UF20"); + connect(uf20UpdateBtn, &QPushButton::clicked, this, &MetadataUpdatePage::onUpdateUF20); + + uf20BtnLayout->addStretch(); + uf20BtnLayout->addWidget(uf20SelectAllBtn); + uf20BtnLayout->addWidget(uf20SelectNoneBtn); + uf20BtnLayout->addWidget(uf20UpdateBtn); + uf20BtnLayout->addStretch(); + + uf20SectionLayout->addLayout(uf20BtnLayout); + mainLayout->addLayout(uf20SectionLayout); +} + +void MetadataUpdatePage::onUF20SelectAll() +{ + m_uf20StdField->setChecked(true); + m_uf20DataType->setChecked(true); + m_uf20ErrorNo->setChecked(true); + m_uf20Table->setChecked(true); + m_uf20Interface->setChecked(true); +} + +void MetadataUpdatePage::onUF20SelectNone() +{ + m_uf20StdField->setChecked(false); + m_uf20DataType->setChecked(false); + m_uf20ErrorNo->setChecked(false); + m_uf20Table->setChecked(false); + m_uf20Interface->setChecked(false); +} + +void MetadataUpdatePage::onUpdateUF20() +{ + QStringList selectedItems; + if (m_uf20StdField->isChecked()) selectedItems << "标准字段"; + if (m_uf20DataType->isChecked()) selectedItems << "数据类型"; + if (m_uf20ErrorNo->isChecked()) selectedItems << "标准错误号"; + if (m_uf20Table->isChecked()) selectedItems << "表结构"; + if (m_uf20Interface->isChecked()) selectedItems << "接口数据"; + + if (selectedItems.isEmpty()) { + QMessageBox::warning(this, "提示", "请选择至少一项更新内容"); + return; + } + + QMessageBox::information(this, "提示", QString("UF20更新功能开发中,已选择: %1").arg(selectedItems.join(", "))); +} + +void MetadataUpdatePage::onUFT3SelectAll() +{ + m_uft3StdField->setChecked(true); + m_uft3DataType->setChecked(true); + m_uft3ErrorNo->setChecked(true); + m_uft3Interface->setChecked(true); +} + +void MetadataUpdatePage::onUFT3SelectNone() +{ + m_uft3StdField->setChecked(false); + m_uft3DataType->setChecked(false); + m_uft3ErrorNo->setChecked(false); + m_uft3Interface->setChecked(false); +} + +void MetadataUpdatePage::onUpdateUFT3() +{ + QStringList selectedItems; + if (m_uft3StdField->isChecked()) selectedItems << "标准字段"; + if (m_uft3DataType->isChecked()) selectedItems << "数据类型"; + if (m_uft3ErrorNo->isChecked()) selectedItems << "标准错误号"; + if (m_uft3Interface->isChecked()) selectedItems << "接口数据"; + + if (selectedItems.isEmpty()) { + QMessageBox::warning(this, "提示", "请选择至少一项更新内容"); + return; + } + + QMessageBox::information(this, "提示", QString("UFT3更新功能开发中,已选择: %1").arg(selectedItems.join(", "))); +} diff --git a/src/pages/metadatupdate/metadatupdatepage.h b/src/pages/metadatupdate/metadatupdatepage.h new file mode 100644 index 0000000..c9e93e6 --- /dev/null +++ b/src/pages/metadatupdate/metadatupdatepage.h @@ -0,0 +1,40 @@ +#ifndef METADATUPDATEPAGE_H +#define METADATUPDATEPAGE_H + +#include +#include "ElaCheckBox.h" +#include "ElaPushButton.h" +#include + +class MetadataUpdatePage : public QWidget +{ + Q_OBJECT + +public: + explicit MetadataUpdatePage(QWidget *parent = nullptr); + ~MetadataUpdatePage(); + +private slots: + void onUF20SelectAll(); + void onUF20SelectNone(); + void onUpdateUF20(); + void onUFT3SelectAll(); + void onUFT3SelectNone(); + void onUpdateUFT3(); + +private: + void initUI(); + + ElaCheckBox *m_uf20StdField; + ElaCheckBox *m_uf20DataType; + ElaCheckBox *m_uf20ErrorNo; + ElaCheckBox *m_uf20Table; + ElaCheckBox *m_uf20Interface; + + ElaCheckBox *m_uft3StdField; + ElaCheckBox *m_uft3DataType; + ElaCheckBox *m_uft3ErrorNo; + ElaCheckBox *m_uft3Interface; +}; + +#endif \ No newline at end of file diff --git a/src/pages/settings/settingspage.cpp b/src/pages/settings/settingspage.cpp index 4153521..dd8ecc3 100644 --- a/src/pages/settings/settingspage.cpp +++ b/src/pages/settings/settingspage.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -11,6 +10,9 @@ #include #include #include +#include "ElaLineEdit.h" +#include "ElaComboBox.h" +#include "ElaPushButton.h" SettingsPage::SettingsPage(QWidget *parent) : QWidget(parent) @@ -40,9 +42,8 @@ void SettingsPage::initUI() QHBoxLayout *uft30Layout = new QHBoxLayout; QLabel *uft30Label = new QLabel("UFT30项目环境路径:"); uft30Label->setMinimumWidth(160); - m_uft30PathEdit = new QLineEdit; - QPushButton *uft30Btn = new QPushButton("浏览..."); - uft30Btn->setStyleSheet("padding: 6px 15px;"); + m_uft30PathEdit = new ElaLineEdit; + ElaPushButton *uft30Btn = new ElaPushButton("浏览..."); connect(uft30Btn, &QPushButton::clicked, this, &SettingsPage::onSelectUFT30Path); uft30Layout->addWidget(uft30Label); uft30Layout->addWidget(m_uft30PathEdit); @@ -53,9 +54,8 @@ void SettingsPage::initUI() QHBoxLayout *uf20Layout = new QHBoxLayout; QLabel *uf20Label = new QLabel("UF20项目环境路径:"); uf20Label->setMinimumWidth(160); - m_uf20PathEdit = new QLineEdit; - QPushButton *uf20Btn = new QPushButton("浏览..."); - uf20Btn->setStyleSheet("padding: 6px 15px;"); + m_uf20PathEdit = new ElaLineEdit; + ElaPushButton *uf20Btn = new ElaPushButton("浏览..."); connect(uf20Btn, &QPushButton::clicked, this, &SettingsPage::onSelectUF20Path); uf20Layout->addWidget(uf20Label); uf20Layout->addWidget(m_uf20PathEdit); @@ -66,9 +66,8 @@ void SettingsPage::initUI() QHBoxLayout *uf20AccountLayout = new QHBoxLayout; QLabel *uf20AccountLabel = new QLabel("UF20账户项目环境路径:"); uf20AccountLabel->setMinimumWidth(160); - m_uf20AccountPathEdit = new QLineEdit; - QPushButton *uf20AccountBtn = new QPushButton("浏览..."); - uf20AccountBtn->setStyleSheet("padding: 6px 15px;"); + m_uf20AccountPathEdit = new ElaLineEdit; + ElaPushButton *uf20AccountBtn = new ElaPushButton("浏览..."); connect(uf20AccountBtn, &QPushButton::clicked, this, &SettingsPage::onSelectUF20AccountPath); uf20AccountLayout->addWidget(uf20AccountLabel); uf20AccountLayout->addWidget(m_uf20AccountPathEdit); @@ -79,9 +78,8 @@ void SettingsPage::initUI() QHBoxLayout *outputLayout = new QHBoxLayout; QLabel *outputLabel = new QLabel("转码生成路径:"); outputLabel->setMinimumWidth(160); - m_outputPathEdit = new QLineEdit; - QPushButton *outputBtn = new QPushButton("浏览..."); - outputBtn->setStyleSheet("padding: 6px 15px;"); + m_outputPathEdit = new ElaLineEdit; + ElaPushButton *outputBtn = new ElaPushButton("浏览..."); connect(outputBtn, &QPushButton::clicked, this, &SettingsPage::onSelectOutputPath); outputLayout->addWidget(outputLabel); outputLayout->addWidget(m_outputPathEdit); @@ -101,7 +99,7 @@ void SettingsPage::initUI() QHBoxLayout *themeLayout = new QHBoxLayout; QLabel *themeLabel = new QLabel("主题模式:"); themeLabel->setMinimumWidth(160); - m_themeCombo = new QComboBox; + m_themeCombo = new ElaComboBox; m_themeCombo->addItems({"日间模式", "夜间模式"}); m_themeCombo->setMinimumWidth(150); connect(m_themeCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &SettingsPage::onThemeChanged); @@ -116,10 +114,9 @@ void SettingsPage::initUI() // 底部按钮 // ========================================== QHBoxLayout *btnLayout = new QHBoxLayout; - QPushButton *saveBtn = new QPushButton("保存设置"); - saveBtn->setStyleSheet("background-color: #9b59b6; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;"); + ElaPushButton *saveBtn = new ElaPushButton("保存设置"); connect(saveBtn, &QPushButton::clicked, this, &SettingsPage::onSaveSettings); - QPushButton *resetBtn = new QPushButton("恢复默认"); + ElaPushButton *resetBtn = new ElaPushButton("恢复默认"); connect(resetBtn, &QPushButton::clicked, this, &SettingsPage::onResetSettings); btnLayout->addStretch(); btnLayout->addWidget(saveBtn); @@ -245,6 +242,18 @@ void SettingsPage::saveToConfigIni() continue; } + if (trimmed.startsWith("uft30pub=")) { + int eqPos = trimmed.indexOf('='); + QString pathValue = trimmed.mid(eqPos + 1); + int pubIndex = pathValue.indexOf("\\upub"); + if (pubIndex >= 0) { + QString pubSuffix = pathValue.mid(pubIndex); + QString newPath = uft30Val + pubSuffix; + newLines << ("uft30pub=" + newPath); + continue; + } + } + if (inProjectPath && !trimmed.isEmpty() && !trimmed.startsWith(';') && !trimmed.startsWith('#')) { int eqPos = trimmed.indexOf('='); if (eqPos > 0) { diff --git a/src/pages/settings/settingspage.h b/src/pages/settings/settingspage.h index f352883..ca4037c 100644 --- a/src/pages/settings/settingspage.h +++ b/src/pages/settings/settingspage.h @@ -2,10 +2,9 @@ #define SETTINGSPAGE_H #include -#include -#include -#include #include +#include "ElaLineEdit.h" +#include "ElaComboBox.h" class SettingsPage : public QWidget { @@ -32,12 +31,12 @@ private: QString getConfigIniPath(); bool isValidUtf8(const QByteArray &data); - QLineEdit *m_uft30PathEdit; - QLineEdit *m_uf20PathEdit; - QLineEdit *m_uf20AccountPathEdit; - QLineEdit *m_outputPathEdit; + ElaLineEdit *m_uft30PathEdit; + ElaLineEdit *m_uf20PathEdit; + ElaLineEdit *m_uf20AccountPathEdit; + ElaLineEdit *m_outputPathEdit; - QComboBox *m_themeCombo; + ElaComboBox *m_themeCombo; }; #endif // SETTINGSPAGE_H \ No newline at end of file diff --git a/src/utils/uf2configreader.cpp b/src/utils/uf2configreader.cpp index 973f710..2f248c7 100644 --- a/src/utils/uf2configreader.cpp +++ b/src/utils/uf2configreader.cpp @@ -33,39 +33,37 @@ bool UF2ConfigReader::loadAllUF20Config() QString filePath = binPath + "/uf2.json"; if (DataCache::instance()->hasUF20Config("uf2.json")) { - LogManager::instance()->log("UF20配置加载 - 已缓存,跳过: uf2.json"); - } else { - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - LogManager::instance()->logError(QString("UF20配置加载 - 无法打开文件: %1").arg(filePath)); - m_failedFiles.append("uf2.json"); - return false; - } - - QByteArray data = file.readAll(); - QJsonDocument doc = QJsonDocument::fromJson(data); - file.close(); - - if (doc.isNull() || !doc.isObject()) { - LogManager::instance()->logError(QString("UF20配置加载 - JSON解析失败: %1").arg(filePath)); - m_failedFiles.append("uf2.json"); - return false; - } - - QJsonObject config = doc.object(); - if (!DataCache::instance()->saveUF20Config("uf2.json", config)) { - LogManager::instance()->logError("UF20配置加载 - 保存失败: uf2.json"); - m_failedFiles.append("uf2.json"); - return false; - } - - LogManager::instance()->log("UF20配置加载 - 成功: uf2.json"); + m_loaded = true; + DataCache::instance()->setDataLoaded(true); + return true; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + LogManager::instance()->logError(QString("UF20配置加载失败 - 无法打开文件: %1").arg(filePath)); + m_failedFiles.append("uf2.json"); + return false; + } + + QByteArray data = file.readAll(); + QJsonDocument doc = QJsonDocument::fromJson(data); + file.close(); + + if (doc.isNull() || !doc.isObject()) { + LogManager::instance()->logError(QString("UF20配置加载失败 - JSON解析失败: %1").arg(filePath)); + m_failedFiles.append("uf2.json"); + return false; + } + + QJsonObject config = doc.object(); + if (!DataCache::instance()->saveUF20Config("uf2.json", config)) { + LogManager::instance()->logError("UF20配置加载失败 - 保存失败: uf2.json"); + m_failedFiles.append("uf2.json"); + return false; } m_loaded = true; DataCache::instance()->setDataLoaded(true); - LogManager::instance()->logInfo("UF20配置加载 - 全部加载完成"); - return true; } @@ -81,7 +79,7 @@ bool UF2ConfigReader::reloadUF20Config() QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - LogManager::instance()->logError(QString("UF20配置加载 - 无法打开文件: %1").arg(filePath)); + LogManager::instance()->logError(QString("UF20配置重新加载失败 - 无法打开文件: %1").arg(filePath)); return false; } @@ -90,18 +88,17 @@ bool UF2ConfigReader::reloadUF20Config() file.close(); if (doc.isNull() || !doc.isObject()) { - LogManager::instance()->logError(QString("UF20配置加载 - JSON解析失败: %1").arg(filePath)); + LogManager::instance()->logError(QString("UF20配置重新加载失败 - JSON解析失败: %1").arg(filePath)); return false; } QJsonObject config = doc.object(); if (!DataCache::instance()->saveUF20Config("uf2.json", config)) { - LogManager::instance()->logError("UF20配置加载 - 保存失败: uf2.json"); + LogManager::instance()->logError("UF20配置重新加载失败 - 保存失败: uf2.json"); return false; } clearCnameCache(); - LogManager::instance()->logInfo("UF20配置重新加载完成"); return true; } @@ -119,14 +116,12 @@ bool UF2ConfigReader::loadCnameCache() m_cnameCache.clear(); if (!DataCache::instance()->initDatabase()) { - LogManager::instance()->logError("Cname缓存加载 - 数据库初始化失败"); + LogManager::instance()->logError("UF20 Cname缓存加载失败 - 数据库初始化失败"); return false; } m_cnameCache = DataCache::instance()->getAllUF20Cnames(); m_cnameCacheLoaded = true; - LogManager::instance()->logInfo(QString("Cname缓存加载完成,共加载 %1 个函数名").arg(m_cnameCache.size())); - return true; } @@ -136,9 +131,7 @@ bool UF2ConfigReader::checkFuncExistsStatic(const QString& funcName) loadCnameCache(); } - bool exists = m_cnameCache.contains(funcName); - LogManager::instance()->log(QString("检查函数名 [%1] 是否存在: %2").arg(funcName).arg(exists ? "是" : "否")); - return exists; + return m_cnameCache.contains(funcName); } bool UF2ConfigReader::checkFunctionExists(const QString& funcName) diff --git a/src/utils/uft3configreader.cpp b/src/utils/uft3configreader.cpp index 90ffaa0..d91794a 100644 --- a/src/utils/uft3configreader.cpp +++ b/src/utils/uft3configreader.cpp @@ -24,7 +24,7 @@ bool UFT3ConfigReader::loadAllUFT3Config() m_failedFiles.clear(); if (!DataCache::instance()->initDatabase()) { - LogManager::instance()->logError("UFT3配置加载 - 数据库初始化失败"); + LogManager::instance()->logError("UFT3配置加载失败 - 数据库初始化失败"); m_failedFiles.append("uft3.json"); return false; } @@ -33,39 +33,37 @@ bool UFT3ConfigReader::loadAllUFT3Config() QString filePath = binPath + "/uft3.json"; if (DataCache::instance()->hasUFT3Config("uft3.json")) { - LogManager::instance()->log("UFT3配置加载 - 已缓存,跳过: uft3.json"); - } else { - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - LogManager::instance()->logError(QString("UFT3配置加载 - 无法打开文件: %1").arg(filePath)); - m_failedFiles.append("uft3.json"); - return false; - } - - QByteArray data = file.readAll(); - QJsonDocument doc = QJsonDocument::fromJson(data); - file.close(); - - if (doc.isNull() || !doc.isObject()) { - LogManager::instance()->logError(QString("UFT3配置加载 - JSON解析失败: %1").arg(filePath)); - m_failedFiles.append("uft3.json"); - return false; - } - - QJsonObject config = doc.object(); - if (!DataCache::instance()->saveUFT3Config("uft3.json", config)) { - LogManager::instance()->logError("UFT3配置加载 - 保存失败: uft3.json"); - m_failedFiles.append("uft3.json"); - return false; - } - - LogManager::instance()->log("UFT3配置加载 - 成功: uft3.json"); + m_loaded = true; + DataCache::instance()->setDataLoaded(true); + return true; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + LogManager::instance()->logError(QString("UFT3配置加载失败 - 无法打开文件: %1").arg(filePath)); + m_failedFiles.append("uft3.json"); + return false; + } + + QByteArray data = file.readAll(); + QJsonDocument doc = QJsonDocument::fromJson(data); + file.close(); + + if (doc.isNull() || !doc.isObject()) { + LogManager::instance()->logError(QString("UFT3配置加载失败 - JSON解析失败: %1").arg(filePath)); + m_failedFiles.append("uft3.json"); + return false; + } + + QJsonObject config = doc.object(); + if (!DataCache::instance()->saveUFT3Config("uft3.json", config)) { + LogManager::instance()->logError("UFT3配置加载失败 - 保存失败: uft3.json"); + m_failedFiles.append("uft3.json"); + return false; } m_loaded = true; DataCache::instance()->setDataLoaded(true); - LogManager::instance()->logInfo("UFT3配置加载 - 全部加载完成"); - return true; } @@ -81,7 +79,7 @@ bool UFT3ConfigReader::reloadUFT3Config() QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - LogManager::instance()->logError(QString("UFT3配置加载 - 无法打开文件: %1").arg(filePath)); + LogManager::instance()->logError(QString("UFT3配置重新加载失败 - 无法打开文件: %1").arg(filePath)); return false; } @@ -90,18 +88,17 @@ bool UFT3ConfigReader::reloadUFT3Config() file.close(); if (doc.isNull() || !doc.isObject()) { - LogManager::instance()->logError(QString("UFT3配置加载 - JSON解析失败: %1").arg(filePath)); + LogManager::instance()->logError(QString("UFT3配置重新加载失败 - JSON解析失败: %1").arg(filePath)); return false; } QJsonObject config = doc.object(); if (!DataCache::instance()->saveUFT3Config("uft3.json", config)) { - LogManager::instance()->logError("UFT3配置加载 - 保存失败: uft3.json"); + LogManager::instance()->logError("UFT3配置重新加载失败 - 保存失败: uft3.json"); return false; } clearCnameCache(); - LogManager::instance()->logInfo("UFT3配置重新加载完成"); return true; } @@ -119,14 +116,12 @@ bool UFT3ConfigReader::loadCnameCache() m_cnameCache.clear(); if (!DataCache::instance()->initDatabase()) { - LogManager::instance()->logError("UFT3 Cname缓存加载 - 数据库初始化失败"); + LogManager::instance()->logError("UFT3 Cname缓存加载失败 - 数据库初始化失败"); return false; } m_cnameCache = DataCache::instance()->getAllUFT3Cnames(); m_cnameCacheLoaded = true; - LogManager::instance()->logInfo(QString("UFT3 Cname缓存加载完成,共加载 %1 个函数名").arg(m_cnameCache.size())); - return true; } @@ -136,9 +131,7 @@ bool UFT3ConfigReader::checkFuncExistsStatic(const QString& funcName) loadCnameCache(); } - bool exists = m_cnameCache.contains(funcName); - LogManager::instance()->log(QString("检查UFT3函数名 [%1] 是否存在: %2").arg(funcName).arg(exists ? "是" : "否")); - return exists; + return m_cnameCache.contains(funcName); } bool UFT3ConfigReader::checkFunctionExists(const QString& funcName)