转码工具页面功能

This commit is contained in:
taocong
2026-05-25 10:18:19 +08:00
commit 3db5fe7f13
107 changed files with 8591 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
#include "aboutpage.h"
#include <QVBoxLayout>
#include <QLabel>
AboutPage::AboutPage(QWidget *parent)
: QWidget(parent)
{
initUI();
}
AboutPage::~AboutPage()
{
}
void AboutPage::initUI()
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(30, 30, 30, 30);
layout->setAlignment(Qt::AlignCenter);
QLabel *logoLabel = new QLabel;
logoLabel->setStyleSheet("font-size: 48px; text-align: center;");
logoLabel->setText("UFT30");
layout->addWidget(logoLabel, 0, Qt::AlignCenter);
QLabel *title = new QLabel("<h1>UFT30 Change Code</h1>");
title->setAlignment(Qt::AlignCenter);
layout->addWidget(title);
QLabel *version = new QLabel("<p style='font-size: 16px;'>版本: 1.0.0</p>");
version->setAlignment(Qt::AlignCenter);
layout->addWidget(version);
QLabel *description = new QLabel("<p style='font-size: 14px; color: #666;'>一款强大的编码转换工具,支持批量转码和非LS格式转换。</p>");
description->setAlignment(Qt::AlignCenter);
layout->addWidget(description);
QLabel *copyright = new QLabel("<p style='font-size: 12px; color: #999;'>Copyright © 2024 UFT30 Team. All rights reserved.</p>");
copyright->setAlignment(Qt::AlignCenter);
layout->addWidget(copyright);
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef ABOUTPAGE_H
#define ABOUTPAGE_H
#include <QWidget>
class AboutPage : public QWidget
{
Q_OBJECT
public:
explicit AboutPage(QWidget *parent = nullptr);
~AboutPage();
private:
void initUI();
};
#endif // ABOUTPAGE_H
+158
View File
@@ -0,0 +1,158 @@
#include "batchconvertpage.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QGroupBox>
#include <QFile>
#include <QCoreApplication>
BatchConvertPage::BatchConvertPage(QWidget *parent)
: QWidget(parent)
{
initUI();
}
BatchConvertPage::~BatchConvertPage()
{
}
void BatchConvertPage::initUI()
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(30, 30, 30, 30);
layout->setSpacing(20);
QGroupBox *funcBox = new QGroupBox("转码功能");
QVBoxLayout *funcLayout = new QVBoxLayout(funcBox);
funcLayout->setSpacing(10);
QLabel *funcLabel = new QLabel("请输入需要转码的功能名称(每行一个):");
funcLayout->addWidget(funcLabel);
m_funcEdit = new QTextEdit;
m_funcEdit->setPlaceholderText("");
m_funcEdit->setMinimumHeight(120);
funcLayout->addWidget(m_funcEdit);
layout->addWidget(funcBox);
QHBoxLayout *btnLayout = new QHBoxLayout;
QPushButton *startBtn = new QPushButton("开始转换");
startBtn->setStyleSheet("background-color: #1abc9c; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;");
connect(startBtn, &QPushButton::clicked, this, &BatchConvertPage::onStartConvert);
QPushButton *clearBtn = new QPushButton("清空");
connect(clearBtn, &QPushButton::clicked, this, &BatchConvertPage::onClearLog);
btnLayout->addStretch();
btnLayout->addWidget(startBtn);
btnLayout->addWidget(clearBtn);
layout->addLayout(btnLayout);
m_logEdit = new QTextEdit;
m_logEdit->setReadOnly(true);
m_logEdit->setStyleSheet("background-color: #2c3e50; color: #ecf0f1;");
m_logEdit->append("转码工具已准备就绪...");
layout->addWidget(m_logEdit);
}
bool BatchConvertPage::saveToCustJson(const QStringList &funcList)
{
QString jsonPath = QCoreApplication::applicationDirPath() + "/uf2touft3/cust.json";
QFile file(jsonPath);
if (!file.open(QIODevice::ReadOnly)) {
m_logEdit->append("[ERROR] 无法打开文件: " + 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\" : [");
}
if (dirStart < 0) {
m_logEdit->append("[ERROR] 未找到 \"dir\" 节点");
return false;
}
int arrayStart = content.indexOf('[', dirStart);
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 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)) {
m_logEdit->append("[ERROR] 无法写入文件: " + jsonPath);
return false;
}
file.write(content.toUtf8());
file.close();
return true;
}
void BatchConvertPage::onStartConvert()
{
QString funcText = m_funcEdit->toPlainText().trimmed();
if (funcText.isEmpty()) {
m_logEdit->append("请输入需要转码的功能名称!");
return;
}
QStringList funcs = funcText.split('\n', Qt::SkipEmptyParts);
QStringList trimmedFuncs;
for (const QString &func : funcs) {
QString trimmed = func.trimmed();
if (!trimmed.isEmpty()) {
trimmedFuncs.append(trimmed);
}
}
if (trimmedFuncs.isEmpty()) {
m_logEdit->append("请输入有效的功能名称!");
return;
}
m_logEdit->append("========================================");
m_logEdit->append("正在写入 cust.json ...");
m_logEdit->append("功能列表:");
for (const QString &func : trimmedFuncs) {
m_logEdit->append(" - " + func + ".service_design");
}
if (saveToCustJson(trimmedFuncs)) {
m_logEdit->append("[OK] cust.json 写入成功!");
} else {
m_logEdit->append("[FAIL] cust.json 写入失败!");
m_logEdit->append("========================================");
return;
}
m_logEdit->append("========================================");
emit startConvert();
}
void BatchConvertPage::onClearLog()
{
m_logEdit->clear();
m_logEdit->append("转码工具已准备就绪...");
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef BATCHCONVERTPAGE_H
#define BATCHCONVERTPAGE_H
#include <QWidget>
#include <QLineEdit>
#include <QTextEdit>
class BatchConvertPage : public QWidget
{
Q_OBJECT
public:
explicit BatchConvertPage(QWidget *parent = nullptr);
~BatchConvertPage();
QTextEdit* getLogEdit() { return m_logEdit; }
signals:
void startConvert();
private slots:
void onStartConvert();
void onClearLog();
private:
void initUI();
bool saveToCustJson(const QStringList &funcList);
QTextEdit *m_funcEdit;
QTextEdit *m_logEdit;
};
#endif // BATCHCONVERTPAGE_H
@@ -0,0 +1,153 @@
#include "functionsearchpage.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QFileDialog>
#include <QMessageBox>
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QSet>
FunctionSearchPage::FunctionSearchPage(QWidget *parent)
: QWidget(parent)
{
initUI();
}
FunctionSearchPage::~FunctionSearchPage()
{
}
void FunctionSearchPage::initUI()
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(30, 30, 30, 30);
mainLayout->setSpacing(15);
m_tabWidget = new QTabWidget;
// ==========================================
// Tab 1: UF20功能搜索
// ==========================================
QWidget *uf20Tab = new QWidget;
QVBoxLayout *uf20Layout = new QVBoxLayout(uf20Tab);
uf20Layout->setSpacing(15);
QHBoxLayout *uf20SearchLayout = new QHBoxLayout;
m_uf20SearchEdit = new QLineEdit;
m_uf20SearchEdit->setPlaceholderText("输入功能名称或关键词搜索...");
m_uf20SearchBtn = new QPushButton("搜索");
m_uf20SearchBtn->setStyleSheet("padding: 8px 25px;");
connect(m_uf20SearchBtn, &QPushButton::clicked, this, &FunctionSearchPage::onSearchUF20);
connect(m_uf20SearchEdit, &QLineEdit::returnPressed, this, &FunctionSearchPage::onSearchUF20);
connect(m_uf20SearchEdit, &QLineEdit::textChanged, this, &FunctionSearchPage::onUF20SearchTextChanged);
uf20SearchLayout->addWidget(m_uf20SearchEdit);
uf20SearchLayout->addWidget(m_uf20SearchBtn);
uf20Layout->addLayout(uf20SearchLayout);
m_uf20ResultTable = new QTableWidget;
m_uf20ResultTable->setColumnCount(4);
m_uf20ResultTable->setHorizontalHeaderLabels({"功能名称", "功能类型", "所属模块", "文件路径"});
m_uf20ResultTable->horizontalHeader()->setStretchLastSection(true);
m_uf20ResultTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
m_uf20ResultTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
m_uf20ResultTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
m_uf20ResultTable->setSelectionBehavior(QAbstractItemView::SelectRows);
m_uf20ResultTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_uf20ResultTable->setAlternatingRowColors(true);
uf20Layout->addWidget(m_uf20ResultTable);
m_uf20StatusLabel = new QLabel("请输入关键词搜索UF20功能");
uf20Layout->addWidget(m_uf20StatusLabel);
m_tabWidget->addTab(uf20Tab, "UF20功能");
// ==========================================
// Tab 2: UFT3功能搜索
// ==========================================
QWidget *uft3Tab = new QWidget;
QVBoxLayout *uft3Layout = new QVBoxLayout(uft3Tab);
uft3Layout->setSpacing(15);
QHBoxLayout *uft3SearchLayout = new QHBoxLayout;
m_uft3SearchEdit = new QLineEdit;
m_uft3SearchEdit->setPlaceholderText("输入功能名称或关键词搜索...");
m_uft3SearchBtn = new QPushButton("搜索");
m_uft3SearchBtn->setStyleSheet("padding: 8px 25px;");
connect(m_uft3SearchBtn, &QPushButton::clicked, this, &FunctionSearchPage::onSearchUFT3);
connect(m_uft3SearchEdit, &QLineEdit::returnPressed, this, &FunctionSearchPage::onSearchUFT3);
connect(m_uft3SearchEdit, &QLineEdit::textChanged, this, &FunctionSearchPage::onUFT3SearchTextChanged);
uft3SearchLayout->addWidget(m_uft3SearchEdit);
uft3SearchLayout->addWidget(m_uft3SearchBtn);
uft3Layout->addLayout(uft3SearchLayout);
m_uft3ResultTable = new QTableWidget;
m_uft3ResultTable->setColumnCount(4);
m_uft3ResultTable->setHorizontalHeaderLabels({"功能名称", "功能类型", "所属模块", "文件路径"});
m_uft3ResultTable->horizontalHeader()->setStretchLastSection(true);
m_uft3ResultTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
m_uft3ResultTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
m_uft3ResultTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
m_uft3ResultTable->setSelectionBehavior(QAbstractItemView::SelectRows);
m_uft3ResultTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_uft3ResultTable->setAlternatingRowColors(true);
uft3Layout->addWidget(m_uft3ResultTable);
m_uft3StatusLabel = new QLabel("请输入关键词搜索UFT3功能");
uft3Layout->addWidget(m_uft3StatusLabel);
m_tabWidget->addTab(uft3Tab, "UFT3功能");
mainLayout->addWidget(m_tabWidget);
}
void FunctionSearchPage::onSearchUF20()
{
QString keyword = m_uf20SearchEdit->text().trimmed();
if (keyword.isEmpty()) {
m_uf20StatusLabel->setText("请输入搜索关键词");
return;
}
m_uf20ResultTable->setRowCount(0);
m_uf20StatusLabel->setText(QString("正在搜索 \"%1\"...").arg(keyword));
m_uf20ResultTable->insertRow(0);
m_uf20ResultTable->setItem(0, 0, new QTableWidgetItem(keyword));
m_uf20ResultTable->setItem(0, 1, new QTableWidgetItem("-"));
m_uf20ResultTable->setItem(0, 2, new QTableWidgetItem("-"));
m_uf20ResultTable->setItem(0, 3, new QTableWidgetItem("-"));
m_uf20StatusLabel->setText(QString("搜索完成,共找到 1 条结果"));
}
void FunctionSearchPage::onSearchUFT3()
{
QString keyword = m_uft3SearchEdit->text().trimmed();
if (keyword.isEmpty()) {
m_uft3StatusLabel->setText("请输入搜索关键词");
return;
}
m_uft3ResultTable->setRowCount(0);
m_uft3StatusLabel->setText(QString("正在搜索 \"%1\"...").arg(keyword));
m_uft3ResultTable->insertRow(0);
m_uft3ResultTable->setItem(0, 0, new QTableWidgetItem(keyword));
m_uft3ResultTable->setItem(0, 1, new QTableWidgetItem("-"));
m_uft3ResultTable->setItem(0, 2, new QTableWidgetItem("-"));
m_uft3ResultTable->setItem(0, 3, new QTableWidgetItem("-"));
m_uft3StatusLabel->setText(QString("搜索完成,共找到 1 条结果"));
}
void FunctionSearchPage::onUF20SearchTextChanged(const QString &text)
{
Q_UNUSED(text);
}
void FunctionSearchPage::onUFT3SearchTextChanged(const QString &text)
{
Q_UNUSED(text);
}
@@ -0,0 +1,41 @@
#ifndef FUNCTIONSEARCHPAGE_H
#define FUNCTIONSEARCHPAGE_H
#include <QWidget>
#include <QLineEdit>
#include <QTabWidget>
#include <QTableWidget>
#include <QPushButton>
#include <QLabel>
class FunctionSearchPage : public QWidget
{
Q_OBJECT
public:
explicit FunctionSearchPage(QWidget *parent = nullptr);
~FunctionSearchPage();
private slots:
void onSearchUF20();
void onSearchUFT3();
void onUF20SearchTextChanged(const QString &text);
void onUFT3SearchTextChanged(const QString &text);
private:
void initUI();
QTabWidget *m_tabWidget;
QLineEdit *m_uf20SearchEdit;
QPushButton *m_uf20SearchBtn;
QTableWidget *m_uf20ResultTable;
QLabel *m_uf20StatusLabel;
QLineEdit *m_uft3SearchEdit;
QPushButton *m_uft3SearchBtn;
QTableWidget *m_uft3ResultTable;
QLabel *m_uft3StatusLabel;
};
#endif // FUNCTIONSEARCHPAGE_H
+62
View File
@@ -0,0 +1,62 @@
#include "helppage.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QTextEdit>
HelpPage::HelpPage(QWidget *parent)
: QWidget(parent)
{
initUI();
}
HelpPage::~HelpPage()
{
}
void HelpPage::initUI()
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(30, 30, 30, 30);
QLabel *title = new QLabel("<h1>使用帮助</h1>");
layout->addWidget(title);
QTextEdit *helpText = new QTextEdit;
helpText->setReadOnly(true);
helpText->setStyleSheet("background-color: white;");
helpText->setHtml(R"(
<h2>批量转码工具</h2>
<p>批量转码工具用于将指定目录下的多个文件从一种编码格式转换为另一种编码格式。</p>
<ul>
<li><strong>源目录:</strong> 选择包含待转换文件的目录</li>
<li><strong>目标目录:</strong> 选择转换后文件的保存目录</li>
<li><strong>文件过滤:</strong> 设置要转换的文件类型,如 *.txt</li>
<li><strong>源编码:</strong> 选择源文件的编码格式</li>
<li><strong>目标编码:</strong> 选择目标编码格式</li>
</ul>
<h2>非LS转码工具</h2>
<p>非LS转码工具用于在LS和非LS格式之间进行转换。</p>
<ul>
<li><strong>非LS转LS:</strong> 将非LS格式转换为LS格式</li>
<li><strong>LS转非LS:</strong> 将LS格式转换为非LS格式</li>
</ul>
<h2>支持的编码格式</h2>
<ul>
<li>GBK</li>
<li>GB2312</li>
<li>UTF-8</li>
<li>UTF-16</li>
<li>ASCII</li>
</ul>
<h2>注意事项</h2>
<ul>
<li>转换前请备份重要文件</li>
<li>确保有足够的磁盘空间</li>
<li>大文件转换可能需要较长时间</li>
</ul>
)");
layout->addWidget(helpText);
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef HELPPAGE_H
#define HELPPAGE_H
#include <QWidget>
class HelpPage : public QWidget
{
Q_OBJECT
public:
explicit HelpPage(QWidget *parent = nullptr);
~HelpPage();
private:
void initUI();
};
#endif // HELPPAGE_H
+121
View File
@@ -0,0 +1,121 @@
#include "nonlsconvertpage.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QGroupBox>
#include <QComboBox>
#include <QFileDialog>
NonLsConvertPage::NonLsConvertPage(QWidget *parent)
: QWidget(parent)
{
initUI();
}
NonLsConvertPage::~NonLsConvertPage()
{
}
void NonLsConvertPage::initUI()
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(30, 30, 30, 30);
layout->setSpacing(20);
QGroupBox *inputBox = new QGroupBox("输入设置");
QVBoxLayout *inputLayout = new QVBoxLayout(inputBox);
inputLayout->setSpacing(15);
QHBoxLayout *srcLayout = new QHBoxLayout;
QLabel *srcLabel = new QLabel("源文件:");
m_srcFileEdit = new QLineEdit;
QPushButton *srcBtn = new QPushButton("浏览");
connect(srcBtn, &QPushButton::clicked, this, &NonLsConvertPage::onBrowseSrcFile);
srcLayout->addWidget(srcLabel);
srcLayout->addWidget(m_srcFileEdit);
srcLayout->addWidget(srcBtn);
inputLayout->addLayout(srcLayout);
QHBoxLayout *dstLayout = new QHBoxLayout;
QLabel *dstLabel = new QLabel("输出文件:");
m_dstFileEdit = new QLineEdit;
QPushButton *dstBtn = new QPushButton("浏览");
connect(dstBtn, &QPushButton::clicked, this, &NonLsConvertPage::onBrowseDstFile);
dstLayout->addWidget(dstLabel);
dstLayout->addWidget(m_dstFileEdit);
dstLayout->addWidget(dstBtn);
inputLayout->addLayout(dstLayout);
layout->addWidget(inputBox);
QGroupBox *optionBox = new QGroupBox("转换选项");
QVBoxLayout *optionLayout = new QVBoxLayout(optionBox);
optionLayout->setSpacing(15);
QHBoxLayout *modeLayout = new QHBoxLayout;
QLabel *modeLabel = new QLabel("转换模式:");
QComboBox *modeCombo = new QComboBox;
modeCombo->addItems({"非LS转LS", "LS转非LS"});
modeLayout->addWidget(modeLabel);
modeLayout->addWidget(modeCombo);
optionLayout->addLayout(modeLayout);
QHBoxLayout *encodingLayout = new QHBoxLayout;
QLabel *encodingLabel = new QLabel("编码格式:");
QComboBox *encodingCombo = new QComboBox;
encodingCombo->addItems({"UTF-8", "GBK", "GB2312"});
encodingLayout->addWidget(encodingLabel);
encodingLayout->addWidget(encodingCombo);
optionLayout->addLayout(encodingLayout);
layout->addWidget(optionBox);
QHBoxLayout *btnLayout = new QHBoxLayout;
QPushButton *startBtn = new QPushButton("开始转换");
startBtn->setStyleSheet("background-color: #3498db; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;");
connect(startBtn, &QPushButton::clicked, this, &NonLsConvertPage::onStartConvert);
QPushButton *previewBtn = new QPushButton("预览");
connect(previewBtn, &QPushButton::clicked, this, &NonLsConvertPage::onPreview);
btnLayout->addStretch();
btnLayout->addWidget(startBtn);
btnLayout->addWidget(previewBtn);
layout->addLayout(btnLayout);
m_resultEdit = new QTextEdit;
m_resultEdit->setReadOnly(true);
m_resultEdit->setStyleSheet("background-color: #2c3e50; color: #ecf0f1;");
m_resultEdit->append("非LS转码工具已准备就绪...");
layout->addWidget(m_resultEdit);
}
void NonLsConvertPage::onBrowseSrcFile()
{
QString file = QFileDialog::getOpenFileName(this, "选择源文件");
if (!file.isEmpty()) {
m_srcFileEdit->setText(file);
}
}
void NonLsConvertPage::onBrowseDstFile()
{
QString file = QFileDialog::getSaveFileName(this, "选择输出文件");
if (!file.isEmpty()) {
m_dstFileEdit->setText(file);
}
}
void NonLsConvertPage::onStartConvert()
{
m_resultEdit->append("开始转换...");
m_resultEdit->append("源文件: " + m_srcFileEdit->text());
m_resultEdit->append("输出文件: " + m_dstFileEdit->text());
m_resultEdit->append("转换完成!");
}
void NonLsConvertPage::onPreview()
{
m_resultEdit->append("预览模式...");
m_resultEdit->append("源文件: " + m_srcFileEdit->text());
m_resultEdit->append("预览完成!");
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef NONLSCONVERTPAGE_H
#define NONLSCONVERTPAGE_H
#include <QWidget>
#include <QLineEdit>
#include <QTextEdit>
class NonLsConvertPage : public QWidget
{
Q_OBJECT
public:
explicit NonLsConvertPage(QWidget *parent = nullptr);
~NonLsConvertPage();
private slots:
void onBrowseSrcFile();
void onBrowseDstFile();
void onStartConvert();
void onPreview();
private:
void initUI();
QLineEdit *m_srcFileEdit;
QLineEdit *m_dstFileEdit;
QTextEdit *m_resultEdit;
};
#endif // NONLSCONVERTPAGE_H
+367
View File
@@ -0,0 +1,367 @@
#include "settingspage.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QGroupBox>
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QSet>
SettingsPage::SettingsPage(QWidget *parent)
: QWidget(parent)
{
initUI();
loadSettings();
}
SettingsPage::~SettingsPage()
{
}
void SettingsPage::initUI()
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(30, 30, 30, 30);
layout->setSpacing(20);
// ==========================================
// 第一部分:环境配置
// ==========================================
QGroupBox *envBox = new QGroupBox("环境配置");
QVBoxLayout *envLayout = new QVBoxLayout(envBox);
envLayout->setSpacing(15);
// UFT30项目环境路径
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;");
connect(uft30Btn, &QPushButton::clicked, this, &SettingsPage::onSelectUFT30Path);
uft30Layout->addWidget(uft30Label);
uft30Layout->addWidget(m_uft30PathEdit);
uft30Layout->addWidget(uft30Btn);
envLayout->addLayout(uft30Layout);
// UF20项目环境路径
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;");
connect(uf20Btn, &QPushButton::clicked, this, &SettingsPage::onSelectUF20Path);
uf20Layout->addWidget(uf20Label);
uf20Layout->addWidget(m_uf20PathEdit);
uf20Layout->addWidget(uf20Btn);
envLayout->addLayout(uf20Layout);
// UF20账户项目环境路径
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;");
connect(uf20AccountBtn, &QPushButton::clicked, this, &SettingsPage::onSelectUF20AccountPath);
uf20AccountLayout->addWidget(uf20AccountLabel);
uf20AccountLayout->addWidget(m_uf20AccountPathEdit);
uf20AccountLayout->addWidget(uf20AccountBtn);
envLayout->addLayout(uf20AccountLayout);
// 转码生成路径
QHBoxLayout *outputLayout = new QHBoxLayout;
QLabel *outputLabel = new QLabel("转码生成路径:");
outputLabel->setMinimumWidth(160);
m_outputPathEdit = new QLineEdit;
QPushButton *outputBtn = new QPushButton("浏览...");
outputBtn->setStyleSheet("padding: 6px 15px;");
connect(outputBtn, &QPushButton::clicked, this, &SettingsPage::onSelectOutputPath);
outputLayout->addWidget(outputLabel);
outputLayout->addWidget(m_outputPathEdit);
outputLayout->addWidget(outputBtn);
envLayout->addLayout(outputLayout);
layout->addWidget(envBox);
// ==========================================
// 第二部分:系统配置
// ==========================================
QGroupBox *systemBox = new QGroupBox("系统配置");
QVBoxLayout *systemLayout = new QVBoxLayout(systemBox);
systemLayout->setSpacing(15);
// 主题切换
QHBoxLayout *themeLayout = new QHBoxLayout;
QLabel *themeLabel = new QLabel("主题模式:");
themeLabel->setMinimumWidth(160);
m_themeCombo = new QComboBox;
m_themeCombo->addItems({"日间模式", "夜间模式"});
m_themeCombo->setMinimumWidth(150);
connect(m_themeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsPage::onThemeChanged);
themeLayout->addWidget(themeLabel);
themeLayout->addWidget(m_themeCombo);
themeLayout->addStretch();
systemLayout->addLayout(themeLayout);
layout->addWidget(systemBox);
// ==========================================
// 底部按钮
// ==========================================
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;");
connect(saveBtn, &QPushButton::clicked, this, &SettingsPage::onSaveSettings);
QPushButton *resetBtn = new QPushButton("恢复默认");
connect(resetBtn, &QPushButton::clicked, this, &SettingsPage::onResetSettings);
btnLayout->addStretch();
btnLayout->addWidget(saveBtn);
btnLayout->addWidget(resetBtn);
layout->addLayout(btnLayout);
// 添加弹性空间
layout->addStretch();
}
void SettingsPage::loadSettings()
{
loadFromConfigIni();
QSettings settings("UFT30", "ChangeCode");
QString theme = settings.value("Theme", "日间模式").toString();
int index = m_themeCombo->findText(theme);
if (index >= 0) {
m_themeCombo->setCurrentIndex(index);
}
}
QString SettingsPage::getConfigIniPath()
{
return QCoreApplication::applicationDirPath() + "/uf2touft3/config.ini";
}
void SettingsPage::loadFromConfigIni()
{
QString iniPath = getConfigIniPath();
if (!QFile::exists(iniPath)) {
return;
}
QFile file(iniPath);
if (!file.open(QIODevice::ReadOnly)) {
return;
}
QByteArray data = file.readAll();
file.close();
QString content = QString::fromLocal8Bit(data);
bool inProjectPath = false;
const QStringList lines = content.split('\n');
for (const QString &rawLine : lines) {
QString line = rawLine.trimmed();
if (line.startsWith('[')) {
inProjectPath = (line == "[projectPath]");
continue;
}
if (!inProjectPath || line.isEmpty() || line.startsWith(';') || line.startsWith('#')) {
continue;
}
int eqPos = line.indexOf('=');
if (eqPos < 0) continue;
QString key = line.left(eqPos).trimmed();
QString value = line.mid(eqPos + 1).trimmed();
value.replace("/", "\\");
if (key == "uft30") m_uft30PathEdit->setText(value);
else if (key == "uf20") m_uf20PathEdit->setText(value);
else if (key == "ufAcct20") m_uf20AccountPathEdit->setText(value);
else if (key == "createPath") m_outputPathEdit->setText(value);
}
}
void SettingsPage::saveToConfigIni()
{
QString iniPath = getConfigIniPath();
QString content;
if (QFile::exists(iniPath)) {
QFile file(iniPath);
if (file.open(QIODevice::ReadOnly)) {
QByteArray data = file.readAll();
file.close();
content = QString::fromLocal8Bit(data);
}
}
auto toWinPath = [](const QString &p) -> QString {
return p.trimmed().replace("/", "\\");
};
QString uft30Val = toWinPath(m_uft30PathEdit->text());
QString uf20Val = toWinPath(m_uf20PathEdit->text());
QString ufAcct20Val = toWinPath(m_uf20AccountPathEdit->text());
QString createPathVal = toWinPath(m_outputPathEdit->text());
bool foundSection = false;
QStringList lines = content.split('\n');
QStringList newLines;
QSet<QString> updatedKeys;
bool alreadyHadProjectPath = false;
for (const QString &rawLine : lines) {
QString line = rawLine;
QString trimmed = rawLine.trimmed();
if (trimmed.startsWith('[')) {
if (foundSection) {
for (const QString &k : QStringList{"uft30", "uf20", "ufAcct20", "createPath"}) {
if (!updatedKeys.contains(k)) {
QString val;
if (k == "uft30") val = uft30Val;
else if (k == "uf20") val = uf20Val;
else if (k == "ufAcct20") val = ufAcct20Val;
else if (k == "createPath") val = createPathVal;
newLines << (k + "=" + val);
updatedKeys.insert(k);
}
}
foundSection = false;
}
if (trimmed == "[projectPath]") {
if (alreadyHadProjectPath) {
continue;
}
alreadyHadProjectPath = true;
foundSection = true;
}
newLines << line;
continue;
}
if (foundSection && !trimmed.isEmpty() && !trimmed.startsWith(';') && !trimmed.startsWith('#')) {
int eqPos = trimmed.indexOf('=');
if (eqPos > 0) {
QString key = trimmed.left(eqPos).trimmed();
if (key == "uft30" || key == "uf20" || key == "ufAcct20" || key == "createPath") {
QString val;
if (key == "uft30") val = uft30Val;
else if (key == "uf20") val = uf20Val;
else if (key == "ufAcct20") val = ufAcct20Val;
else if (key == "createPath") val = createPathVal;
newLines << (key + "=" + val);
updatedKeys.insert(key);
continue;
}
}
}
newLines << line;
}
if (foundSection) {
for (const QString &k : QStringList{"uft30", "uf20", "ufAcct20", "createPath"}) {
if (!updatedKeys.contains(k)) {
QString val;
if (k == "uft30") val = uft30Val;
else if (k == "uf20") val = uf20Val;
else if (k == "ufAcct20") val = ufAcct20Val;
else if (k == "createPath") val = createPathVal;
newLines << (k + "=" + val);
}
}
} else {
newLines << "";
newLines << "[projectPath]";
newLines << ("uft30=" + uft30Val);
newLines << ("uf20=" + uf20Val);
newLines << ("ufAcct20=" + ufAcct20Val);
newLines << ("createPath=" + createPathVal);
}
QFile outFile(iniPath);
if (outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QByteArray outData = newLines.join("\n").toLocal8Bit();
outFile.write(outData);
outFile.close();
}
}
void SettingsPage::onSaveSettings()
{
QSettings settings("UFT30", "ChangeCode");
settings.setValue("Theme", m_themeCombo->currentText());
saveToConfigIni();
QMessageBox::information(this, "保存成功", "配置已保存!");
}
void SettingsPage::onResetSettings()
{
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "确认重置", "确定要恢复所有默认设置吗?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
m_uft30PathEdit->clear();
m_uf20PathEdit->clear();
m_uf20AccountPathEdit->clear();
m_outputPathEdit->clear();
m_themeCombo->setCurrentIndex(0);
saveToConfigIni();
QSettings settings("UFT30", "ChangeCode");
settings.clear();
QMessageBox::information(this, "重置成功", "已恢复默认设置!");
}
}
void SettingsPage::onSelectUFT30Path()
{
QString dir = QFileDialog::getExistingDirectory(this, "选择UFT30项目环境路径", m_uft30PathEdit->text());
if (!dir.isEmpty()) {
m_uft30PathEdit->setText(dir);
}
}
void SettingsPage::onSelectUF20Path()
{
QString dir = QFileDialog::getExistingDirectory(this, "选择UF20项目环境路径", m_uf20PathEdit->text());
if (!dir.isEmpty()) {
m_uf20PathEdit->setText(dir);
}
}
void SettingsPage::onSelectUF20AccountPath()
{
QString dir = QFileDialog::getExistingDirectory(this, "选择UF20账户项目环境路径", m_uf20AccountPathEdit->text());
if (!dir.isEmpty()) {
m_uf20AccountPathEdit->setText(dir);
}
}
void SettingsPage::onSelectOutputPath()
{
QString dir = QFileDialog::getExistingDirectory(this, "选择转码生成路径", m_outputPathEdit->text());
if (!dir.isEmpty()) {
m_outputPathEdit->setText(dir);
}
}
void SettingsPage::onThemeChanged(int index)
{
// 这里可以添加主题切换的逻辑
Q_UNUSED(index);
// 暂时只保存设置,切换效果可以在后续实现
}
+42
View File
@@ -0,0 +1,42 @@
#ifndef SETTINGSPAGE_H
#define SETTINGSPAGE_H
#include <QWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QComboBox>
#include <QSettings>
class SettingsPage : public QWidget
{
Q_OBJECT
public:
explicit SettingsPage(QWidget *parent = nullptr);
~SettingsPage();
private slots:
void onSaveSettings();
void onResetSettings();
void onSelectUFT30Path();
void onSelectUF20Path();
void onSelectUF20AccountPath();
void onSelectOutputPath();
void onThemeChanged(int index);
private:
void initUI();
void loadSettings();
void saveToConfigIni();
void loadFromConfigIni();
QString getConfigIniPath();
QLineEdit *m_uft30PathEdit;
QLineEdit *m_uf20PathEdit;
QLineEdit *m_uf20AccountPathEdit;
QLineEdit *m_outputPathEdit;
QComboBox *m_themeCombo;
};
#endif // SETTINGSPAGE_H