From faae203eb1999ad345a6892e46fcda78dc335cb4 Mon Sep 17 00:00:00 2001 From: zzh <838331105@qq.com> Date: Wed, 24 Sep 2025 10:45:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Eqt=E7=A8=8B=E5=BA=8Fota?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 + src/mainwindow.cpp | 324 ++++++++++++++++++++++++++++++++++- src/mainwindow.h | 21 +++ src/updatesettingsdialog.cpp | 249 +++++++++++++++++++++++++++ src/updatesettingsdialog.h | 51 ++++++ 5 files changed, 642 insertions(+), 5 deletions(-) create mode 100644 src/updatesettingsdialog.cpp create mode 100644 src/updatesettingsdialog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 930de8b..48af6b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,12 +20,14 @@ set(SOURCES src/mainwindow.cpp src/mqttclient.cpp src/lightstripmanager.cpp + src/updatesettingsdialog.cpp ) set(HEADERS src/mainwindow.h src/mqttclient.h src/lightstripmanager.h + src/updatesettingsdialog.h ) add_executable(QtDemo ${SOURCES} ${HEADERS} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d90ade8..5520fa5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,12 +1,13 @@ #include "mainwindow.h" #include "lightstripmanager.h" +#include "updatesettingsdialog.h" #include #include #include -//#include -//#include -//#include -//#include +#include +#include +#include +#include #include #include #include @@ -15,12 +16,24 @@ #include #include #include +#include +#include +#include +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), otaOperationPending(false), isUpgradeOperation(true) { // 初始化设置对象 settings = new QSettings("TuxiApp", "LightStripSN", this); + + // 初始化更新相关变量 + currentVersion = "1.3.0"; // 当前程序版本 + updateServerUrl = settings->value("updateServerUrl", "http://180.163.74.83:8001/version").toString(); + updateNetworkManager = new QNetworkAccessManager(this); + updateCheckReply = nullptr; + updateDownloadReply = nullptr; + downloadedUpdatePath = ""; setupUI(); @@ -98,7 +111,7 @@ void MainWindow::showVersionUpdateInfo() */ void MainWindow::setupUI() { - setWindowTitle("兔喜Test1.2 Author:Zhangzhenghao Email:zzh9953477@gmail.com"); + setWindowTitle("兔喜Test1.5 Author:Zhangzhenghao Email:zzh9953477@gmail.com"); // 参考qt_bak的合理尺寸设置,增加竖向高度 setMinimumSize(850, 720); // 增加最小高度 @@ -333,6 +346,27 @@ void MainWindow::setupUI() { "}" ); snHeaderLayout->addWidget(searchLightStripBtn); + + // 添加清除按钮 + clearSnBtn = new QPushButton("清除列表", this); + clearSnBtn->setMinimumHeight(26); + clearSnBtn->setMinimumWidth(80); + clearSnBtn->setStyleSheet( + "QPushButton { " + " background-color: #f44336; " + " color: white; " + " padding: 4px 10px; " + " font-weight: bold; " + " border-radius: 6px; " + " font-size: 12px; " + " border: none; " + "} " + "QPushButton:hover { " + " background-color: #d32f2f; " + "}" + ); + snHeaderLayout->addWidget(clearSnBtn); + snLayout->addLayout(snHeaderLayout); // 打开管理器按钮 @@ -1415,6 +1449,17 @@ void MainWindow::createMenus() QAction *useGuideAction = helpMenu->addAction("使用说明(&U)"); connect(useGuideAction, &QAction::triggered, this, &MainWindow::showUseGuide); + + // 添加分隔线 + helpMenu->addSeparator(); + + // 添加手动检查更新菜单项 + QAction *checkUpdateAction = helpMenu->addAction("检查更新(&C)"); + connect(checkUpdateAction, &QAction::triggered, this, &MainWindow::checkForUpdates); + + // 添加更新设置菜单项 + QAction *updateSettingsAction = helpMenu->addAction("更新设置(&S)"); + connect(updateSettingsAction, &QAction::triggered, this, &MainWindow::onUpdateSettingsClicked); } void MainWindow::showAbout() @@ -1457,3 +1502,272 @@ QString MainWindow::getTextColorForTheme() const { // 如果背景较暗(亮度小于0.5),使用白色文字;否则使用黑色文字 return (luminance < 0.5) ? "white" : "black"; } + +// 更新功能实现 +void MainWindow::checkForUpdates() +{ + if (updateCheckReply) { + updateCheckReply->abort(); + updateCheckReply = nullptr; + } + + QNetworkRequest request{QUrl(updateServerUrl)}; + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + updateCheckReply = updateNetworkManager->get(request); + connect(updateCheckReply, &QNetworkReply::finished, this, &MainWindow::onUpdateCheckFinished); +} + +void MainWindow::onUpdateCheckFinished() +{ + if (!updateCheckReply) return; + + if (updateCheckReply->error() == QNetworkReply::NoError) { + QByteArray data = updateCheckReply->readAll(); + QJsonDocument doc = QJsonDocument::fromJson(data); + QJsonObject obj = doc.object(); + + QString latestVersion = obj["version"].toString(); + QString downloadUrl = obj["downloadUrl"].toString(); + QString changelog = obj["changelog"].toString(); + + if (compareVersions(currentVersion, latestVersion) < 0) { + showUpdateDialog(latestVersion, downloadUrl, changelog); + } else { + QMessageBox::information(this, "检查更新", "当前已是最新版本!"); + } + } else { + QMessageBox::warning(this, "检查更新失败", + QString("无法连接到更新服务器:%1").arg(updateCheckReply->errorString())); + } + + updateCheckReply->deleteLater(); + updateCheckReply = nullptr; +} + +void MainWindow::showUpdateDialog(const QString &version, const QString &downloadUrl, const QString &changelog) +{ + QMessageBox msgBox(this); + msgBox.setWindowTitle("发现新版本"); + msgBox.setText(QString("发现新版本 %1").arg(version)); + msgBox.setDetailedText(changelog); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + QAbstractButton *yesButton = msgBox.button(QMessageBox::Yes); + QAbstractButton *noButton = msgBox.button(QMessageBox::No); + if (yesButton) yesButton->setText("立即更新"); + if (noButton) noButton->setText("稍后更新"); + + if (msgBox.exec() == QMessageBox::Yes) { + downloadUpdate(downloadUrl); + } +} + +void MainWindow::downloadUpdate(const QString &downloadUrl) +{ + if (updateDownloadReply) { + updateDownloadReply->abort(); + updateDownloadReply = nullptr; + } + + QNetworkRequest request{QUrl(downloadUrl)}; + updateDownloadReply = updateNetworkManager->get(request); + + connect(updateDownloadReply, &QNetworkReply::downloadProgress, + this, &MainWindow::onUpdateDownloadProgress); + connect(updateDownloadReply, &QNetworkReply::finished, + this, &MainWindow::onUpdateDownloadFinished); + + // 显示下载进度对话框 + QProgressDialog *progressDialog = new QProgressDialog("正在下载更新...", "取消", 0, 100, this); + progressDialog->setWindowModality(Qt::WindowModal); + progressDialog->show(); + + connect(progressDialog, &QProgressDialog::canceled, [this]() { + if (updateDownloadReply) { + updateDownloadReply->abort(); + } + }); +} + +void MainWindow::onUpdateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + if (bytesTotal > 0) { + int progress = static_cast((bytesReceived * 100) / bytesTotal); + // 更新进度条 + QProgressDialog *progressDialog = findChild(); + if (progressDialog) { + progressDialog->setValue(progress); + } + } +} + +void MainWindow::onUpdateDownloadFinished() +{ + if (!updateDownloadReply) return; + + QProgressDialog *progressDialog = findChild(); + if (progressDialog) { + progressDialog->close(); + progressDialog->deleteLater(); + } + + if (updateDownloadReply->error() == QNetworkReply::NoError) { + // 保存下载的文件 + QByteArray data = updateDownloadReply->readAll(); + QString fileName = QUrl(updateDownloadReply->url()).fileName(); + downloadedUpdatePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + fileName; + + QFile file(downloadedUpdatePath); + if (file.open(QIODevice::WriteOnly)) { + file.write(data); + file.close(); + + QMessageBox msgBox(this); + msgBox.setWindowTitle("下载完成"); + msgBox.setText("更新包下载完成,是否立即安装?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + QAbstractButton *yesButton = msgBox.button(QMessageBox::Yes); + QAbstractButton *noButton = msgBox.button(QMessageBox::No); + if (yesButton) yesButton->setText("立即安装"); + if (noButton) noButton->setText("稍后安装"); + + if (msgBox.exec() == QMessageBox::Yes) { + installUpdate(); + } + } else { + QMessageBox::critical(this, "下载失败", "无法保存更新文件!"); + } + } else { + QMessageBox::warning(this, "下载失败", + QString("下载更新失败:%1").arg(updateDownloadReply->errorString())); + } + + updateDownloadReply->deleteLater(); + updateDownloadReply = nullptr; +} + +void MainWindow::installUpdate() +{ + if (downloadedUpdatePath.isEmpty() || !QFile::exists(downloadedUpdatePath)) { + QMessageBox::warning(this, "安装失败", "找不到更新文件!"); + return; + } + + // 根据文件类型执行不同的安装逻辑 + if (downloadedUpdatePath.endsWith(".deb")) { + // Debian包安装 + QProcess::startDetached("pkexec", QStringList() << "dpkg" << "-i" << downloadedUpdatePath); + } else if (downloadedUpdatePath.endsWith(".rpm")) { + // RPM包安装 + QProcess::startDetached("pkexec", QStringList() << "rpm" << "-i" << downloadedUpdatePath); + } else if (downloadedUpdatePath.endsWith(".AppImage")) { + // AppImage替换 + QString currentPath = QCoreApplication::applicationFilePath(); + QString backupPath = currentPath + ".backup"; + + // 备份当前程序 + QFile::copy(currentPath, backupPath); + + // 替换程序文件 + QFile::remove(currentPath); + QFile::copy(downloadedUpdatePath, currentPath); + QFile::setPermissions(currentPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | + QFile::ReadGroup | QFile::ExeGroup | + QFile::ReadOther | QFile::ExeOther); + + QMessageBox::information(this, "安装完成", "更新安装完成,请重启程序!"); + QApplication::quit(); + } else { + // 普通可执行文件替换(如QtDemo) + QString currentPath = QCoreApplication::applicationFilePath(); + QString currentDir = QFileInfo(currentPath).absolutePath(); + QString currentFileName = QFileInfo(currentPath).fileName(); + QString backupPath = currentPath + ".backup"; + QString tempPath = currentPath + ".new"; + + // 备份当前程序 + QFile::copy(currentPath, backupPath); + + // 先将新文件复制到临时位置 + if (!QFile::copy(downloadedUpdatePath, tempPath)) { + QMessageBox::warning(this, "安装失败", "无法复制更新文件!"); + return; + } + + // 设置临时文件权限 + QFile::setPermissions(tempPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | + QFile::ReadGroup | QFile::ExeGroup | + QFile::ReadOther | QFile::ExeOther); + + // 创建更新脚本 + QString scriptPath = currentDir + "/update_and_restart.sh"; + QFile scriptFile(scriptPath); + if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream out(&scriptFile); + out << "#!/bin/bash\n"; + out << "sleep 2\n"; // 等待当前进程完全退出 + out << "# 移除旧文件并重命名新文件\n"; + out << "rm -f \"" << currentPath << "\"\n"; + out << "mv \"" << tempPath << "\" \"" << currentPath << "\"\n"; + out << "chmod +x \"" << currentPath << "\"\n"; + out << "cd \"" << currentDir << "\"\n"; + out << "# 启动新程序\n"; + out << "nohup ./" << currentFileName << " > /dev/null 2>&1 &\n"; + out << "# 清理脚本文件\n"; + out << "sleep 1\n"; + out << "rm -f \"" << scriptPath << "\"\n"; + scriptFile.close(); + + // 设置脚本可执行权限 + QFile::setPermissions(scriptPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | + QFile::ReadGroup | QFile::ExeGroup | + QFile::ReadOther | QFile::ExeOther); + + // 启动更新脚本并退出当前程序 + QProcess::startDetached("/bin/bash", QStringList() << scriptPath); + QMessageBox::information(this, "安装完成", "更新安装完成,程序将自动重启!"); + + // 延迟退出,确保脚本有时间启动 + QTimer::singleShot(500, []() { + QApplication::quit(); + }); + } else { + QMessageBox::warning(this, "安装失败", "无法创建更新脚本!"); + QFile::remove(tempPath); // 清理临时文件 + } + } +} + +int MainWindow::compareVersions(const QString &version1, const QString &version2) +{ + QStringList v1Parts = version1.split('.'); + QStringList v2Parts = version2.split('.'); + + int maxParts = qMax(v1Parts.size(), v2Parts.size()); + + for (int i = 0; i < maxParts; ++i) { + int v1Part = (i < v1Parts.size()) ? v1Parts[i].toInt() : 0; + int v2Part = (i < v2Parts.size()) ? v2Parts[i].toInt() : 0; + + if (v1Part < v2Part) return -1; + if (v1Part > v2Part) return 1; + } + + return 0; +} + +void MainWindow::onUpdateSettingsClicked() +{ + UpdateSettingsDialog dialog(this); + if (dialog.exec() == QDialog::Accepted) { + // 更新本地设置 + updateServerUrl = dialog.getUpdateServerUrl(); + settings->setValue("updateServerUrl", updateServerUrl); + settings->setValue("autoCheckUpdates", dialog.isAutoCheckEnabled()); + settings->setValue("checkInterval", dialog.getCheckInterval()); + + QMessageBox::information(this, "设置保存", "更新设置已保存!"); + } +} diff --git a/src/mainwindow.h b/src/mainwindow.h index ebd7cad..017c737 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -62,6 +62,13 @@ private slots: void onClearSnListClicked(); void onLightStripManagerClosed(); void onDeviceSnChanged(); // 新增:设备SN变化槽函数 + + // 更新相关槽函数 + void checkForUpdates(); + void onUpdateCheckFinished(); + void onUpdateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void onUpdateDownloadFinished(); + void onUpdateSettingsClicked(); private: void setupUI(); @@ -77,6 +84,12 @@ private: void sendSearchLightStripCommand(); void openLightStripManager(); // 添加这个声明 + // 更新相关函数 + void showUpdateDialog(const QString &version, const QString &downloadUrl, const QString &changelog); + void downloadUpdate(const QString &downloadUrl); + void installUpdate(); + int compareVersions(const QString &version1, const QString &version2); + // 新增:公共接口 QString getDeviceSn() const; QString getTextColorForTheme() const; @@ -142,6 +155,14 @@ private: // MQTT客户端 MqttClient *mqttClient; + // 更新相关成员变量 + QString currentVersion; + QString updateServerUrl; + QNetworkAccessManager *updateNetworkManager; + QNetworkReply *updateCheckReply; + QNetworkReply *updateDownloadReply; + QString downloadedUpdatePath; + // 数据管理 QSet uniqueSnSet; QList lightStripCheckBoxes; // 添加复选框列表 diff --git a/src/updatesettingsdialog.cpp b/src/updatesettingsdialog.cpp new file mode 100644 index 0000000..8c77768 --- /dev/null +++ b/src/updatesettingsdialog.cpp @@ -0,0 +1,249 @@ +#include "updatesettingsdialog.h" +#include +#include +#include +#include +#include +#include +#include + +UpdateSettingsDialog::UpdateSettingsDialog(QWidget *parent) + : QDialog(parent), + serverUrlEdit(nullptr), + autoCheckBox(nullptr), + checkIntervalEdit(nullptr), + testBtn(nullptr), + resetBtn(nullptr), + okBtn(nullptr), + cancelBtn(nullptr), + settings(nullptr) +{ + settings = new QSettings("TuxiApp", "LightStripSN", this); + setupUI(); + loadSettings(); +} + +UpdateSettingsDialog::~UpdateSettingsDialog() +{ +} + +void UpdateSettingsDialog::setupUI() +{ + qDebug() << "开始设置UpdateSettingsDialog UI..."; + + setWindowTitle("更新设置"); + setFixedSize(400, 300); + setModal(true); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + if (!mainLayout) { + qDebug() << "错误: 无法创建主布局"; + return; + } + + // 服务器设置组 + QGroupBox *serverGroup = new QGroupBox("服务器设置", this); + if (!serverGroup) { + qDebug() << "错误: 无法创建服务器设置组"; + return; + } + + QFormLayout *serverLayout = new QFormLayout(serverGroup); + if (!serverLayout) { + qDebug() << "错误: 无法创建服务器布局"; + return; + } + + serverUrlEdit = new QLineEdit(this); + if (!serverUrlEdit) { + qDebug() << "错误: 无法创建服务器URL编辑框"; + return; + } + serverUrlEdit->setPlaceholderText("http://180.163.74.83:8001/version"); + serverLayout->addRow("更新服务器地址:", serverUrlEdit); + + QHBoxLayout *testLayout = new QHBoxLayout(); + testBtn = new QPushButton("测试连接", this); + resetBtn = new QPushButton("恢复默认", this); + + if (!testBtn || !resetBtn) { + qDebug() << "错误: 无法创建测试或重置按钮"; + return; + } + + testLayout->addWidget(testBtn); + testLayout->addWidget(resetBtn); + testLayout->addStretch(); + serverLayout->addRow("", testLayout); + + mainLayout->addWidget(serverGroup); + + // 自动检查设置组 + QGroupBox *autoGroup = new QGroupBox("自动检查设置", this); + QFormLayout *autoLayout = new QFormLayout(autoGroup); + + autoCheckBox = new QCheckBox("启用自动检查更新", this); + autoLayout->addRow(autoCheckBox); + + checkIntervalEdit = new QLineEdit(this); + checkIntervalEdit->setPlaceholderText("24"); + QLabel *intervalLabel = new QLabel("检查间隔(小时):", this); + autoLayout->addRow(intervalLabel, checkIntervalEdit); + + // 当自动检查被禁用时,禁用间隔设置 + connect(autoCheckBox, &QCheckBox::toggled, [this, intervalLabel](bool checked) { + checkIntervalEdit->setEnabled(checked); + intervalLabel->setEnabled(checked); + }); + + mainLayout->addWidget(autoGroup); + + // 按钮布局 + QHBoxLayout *buttonLayout = new QHBoxLayout(); + buttonLayout->addStretch(); + + okBtn = new QPushButton("确定", this); + cancelBtn = new QPushButton("取消", this); + + buttonLayout->addWidget(okBtn); + buttonLayout->addWidget(cancelBtn); + + mainLayout->addLayout(buttonLayout); + + // 连接信号槽 + connect(okBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onOkClicked); + connect(cancelBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onCancelClicked); + connect(testBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onTestConnectionClicked); + connect(resetBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onResetToDefaultClicked); + + qDebug() << "UpdateSettingsDialog UI设置完成"; +} + + +void UpdateSettingsDialog::loadSettings() +{ + QString defaultUrl = "http://180.163.74.83:8001/version"; + serverUrlEdit->setText(settings->value("updateServerUrl", defaultUrl).toString()); + autoCheckBox->setChecked(settings->value("autoCheckUpdates", true).toBool()); + checkIntervalEdit->setText(settings->value("checkInterval", 24).toString()); + + // 触发复选框状态变化以更新UI + emit autoCheckBox->toggled(autoCheckBox->isChecked()); +} + +void UpdateSettingsDialog::saveSettings() +{ + settings->setValue("updateServerUrl", serverUrlEdit->text().trimmed()); + settings->setValue("autoCheckUpdates", autoCheckBox->isChecked()); + settings->setValue("checkInterval", checkIntervalEdit->text().toInt()); + settings->sync(); +} + +QString UpdateSettingsDialog::getUpdateServerUrl() const +{ + return serverUrlEdit->text().trimmed(); +} + +bool UpdateSettingsDialog::isAutoCheckEnabled() const +{ + return autoCheckBox->isChecked(); +} + +int UpdateSettingsDialog::getCheckInterval() const +{ + return checkIntervalEdit->text().toInt(); +} + +void UpdateSettingsDialog::onOkClicked() +{ + // 验证输入 + QString url = serverUrlEdit->text().trimmed(); + if (url.isEmpty()) { + QMessageBox::warning(this, "输入错误", "请输入更新服务器地址!"); + return; + } + + if (!url.startsWith("http://") && !url.startsWith("https://")) { + QMessageBox::warning(this, "输入错误", "服务器地址必须以 http:// 或 https:// 开头!"); + return; + } + + int interval = checkIntervalEdit->text().toInt(); + if (autoCheckBox->isChecked() && (interval < 1 || interval > 168)) { + QMessageBox::warning(this, "输入错误", "检查间隔必须在1-168小时之间!"); + return; + } + + saveSettings(); + accept(); +} + +void UpdateSettingsDialog::onCancelClicked() +{ + reject(); +} + +void UpdateSettingsDialog::onTestConnectionClicked() +{ + QString url = serverUrlEdit->text().trimmed(); + if (url.isEmpty()) { + QMessageBox::warning(this, "测试失败", "请先输入服务器地址!"); + return; + } + + testConnection(); +} + +void UpdateSettingsDialog::onResetToDefaultClicked() +{ + int ret = QMessageBox::question(this, "确认重置", + "确定要恢复默认设置吗?", + QMessageBox::Yes | QMessageBox::No); + if (ret == QMessageBox::Yes) { + serverUrlEdit->setText("http://180.163.74.83:8001/version"); + autoCheckBox->setChecked(true); + checkIntervalEdit->setText("24"); + } +} + +void UpdateSettingsDialog::testConnection() +{ + testBtn->setEnabled(false); + testBtn->setText("测试中..."); + + QNetworkAccessManager *manager = new QNetworkAccessManager(this); + QNetworkRequest request; + request.setUrl(QUrl(serverUrlEdit->text().trimmed())); + request.setRawHeader("User-Agent", "LightStripSN-Updater/1.0"); + + // 设置超时 + QTimer *timer = new QTimer(this); + timer->setSingleShot(true); + + QNetworkReply *reply = manager->get(request); + + connect(timer, &QTimer::timeout, [this, reply]() { + reply->abort(); + testBtn->setEnabled(true); + testBtn->setText("测试连接"); + QMessageBox::warning(this, "连接超时", "连接服务器超时,请检查网络或服务器地址!"); + }); + + connect(reply, &QNetworkReply::finished, [this, reply, timer]() { + timer->stop(); + testBtn->setEnabled(true); + testBtn->setText("测试连接"); + + if (reply->error() == QNetworkReply::NoError) { + QMessageBox::information(this, "连接成功", "服务器连接正常!"); + } else { + QMessageBox::warning(this, "连接失败", + QString("连接失败: %1").arg(reply->errorString())); + } + + reply->deleteLater(); + timer->deleteLater(); + }); + + timer->start(10000); // 10秒超时 +} \ No newline at end of file diff --git a/src/updatesettingsdialog.h b/src/updatesettingsdialog.h new file mode 100644 index 0000000..3456c6c --- /dev/null +++ b/src/updatesettingsdialog.h @@ -0,0 +1,51 @@ +#ifndef UPDATESETTINGSDIALOG_H +#define UPDATESETTINGSDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class UpdateSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit UpdateSettingsDialog(QWidget *parent = nullptr); + ~UpdateSettingsDialog(); + + QString getUpdateServerUrl() const; + bool isAutoCheckEnabled() const; + int getCheckInterval() const; + +private slots: + void onOkClicked(); + void onCancelClicked(); + void onTestConnectionClicked(); + void onResetToDefaultClicked(); + +private: + void setupUI(); + void loadSettings(); + void saveSettings(); + void testConnection(); + + QLineEdit *serverUrlEdit; + QCheckBox *autoCheckBox; + QLineEdit *checkIntervalEdit; + QPushButton *testBtn; + QPushButton *resetBtn; + QPushButton *okBtn; + QPushButton *cancelBtn; + + QSettings *settings; +}; + +#endif // UPDATESETTINGSDIALOG_H \ No newline at end of file