diff --git a/src/ui/form/basecontroller.cpp b/src/ui/form/basecontroller.cpp index 9b90b310..a132efaa 100644 --- a/src/ui/form/basecontroller.cpp +++ b/src/ui/form/basecontroller.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,11 @@ WindowManager *BaseController::windowManager() const return IoC(); } +AutoUpdateManager *BaseController::autoUpdateManager() const +{ + return IoC(); +} + TaskManager *BaseController::taskManager() const { return IoC(); diff --git a/src/ui/form/basecontroller.h b/src/ui/form/basecontroller.h index 991cf775..f2d8e541 100644 --- a/src/ui/form/basecontroller.h +++ b/src/ui/form/basecontroller.h @@ -3,6 +3,7 @@ #include +class AutoUpdateManager; class ConfAppManager; class ConfManager; class ConfRuleManager; @@ -38,6 +39,7 @@ public: DriverManager *driverManager() const; TranslationManager *translationManager() const; WindowManager *windowManager() const; + AutoUpdateManager *autoUpdateManager() const; TaskManager *taskManager() const; signals: diff --git a/src/ui/form/home/pages/aboutpage.cpp b/src/ui/form/home/pages/aboutpage.cpp index 0f64b621..6f0cea03 100644 --- a/src/ui/form/home/pages/aboutpage.cpp +++ b/src/ui/form/home/pages/aboutpage.cpp @@ -2,11 +2,13 @@ #include #include +#include #include #include #include
#include +#include #include #include #include @@ -36,6 +38,7 @@ AboutPage::AboutPage(HomeController *ctrl, QWidget *parent) : HomeBasePage(ctrl, void AboutPage::onRetranslateUi() { m_btDownload->setText(tr("Download")); + m_btInstall->setText(tr("Install")); m_btCheckUpdate->setText(tr("Check for update")); retranslateNewVersionBox(); @@ -48,13 +51,14 @@ void AboutPage::retranslateNewVersionBox() void AboutPage::setupUi() { - auto layout = new QVBoxLayout(); - // New Version Group Box setupNewVersionBox(); - setupNewVersionUpdate(); - layout->addWidget(m_gbNewVersion, 0, Qt::AlignHCenter); + setupNewVersionUpdate(); + setupAutoUpdate(); + + auto layout = new QVBoxLayout(); + layout->addWidget(m_gbNewVersion, 0, Qt::AlignHCenter); layout->addStretch(); this->setLayout(layout); @@ -71,6 +75,9 @@ void AboutPage::setupNewVersionBox() m_labelArea = ControlUtil::wrapToScrollArea(m_labelRelease); m_labelArea->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); + // Progress Bar + m_progressBar = new QProgressBar(); + // Buttons auto buttonsLayout = setupButtonsLayout(); @@ -78,6 +85,7 @@ void AboutPage::setupNewVersionBox() layout->setSpacing(10); layout->addWidget(m_labelArea); + layout->addWidget(m_progressBar); layout->addLayout(buttonsLayout); m_gbNewVersion = new QGroupBox(); @@ -88,21 +96,20 @@ void AboutPage::setupNewVersionBox() QLayout *AboutPage::setupButtonsLayout() { // Download - m_btDownload = ControlUtil::createFlatToolButton(":/icons/download.png"); + m_btDownload = ControlUtil::createFlatToolButton( + ":/icons/download.png", [&] { autoUpdateManager()->startDownload(); }); - connect(m_btDownload, &QAbstractButton::clicked, ctrl(), &BaseController::onLinkClicked); + // Install + m_btInstall = ControlUtil::createFlatToolButton( + ":/icons/tick.png", [&] { autoUpdateManager()->runInstaller(); }); // Check Update m_btCheckUpdate = ControlUtil::createFlatToolButton( ":/icons/play.png", [&] { taskManager()->runTask(TaskInfo::UpdateChecker); }); - auto layout = new QHBoxLayout(); - layout->setSpacing(10); - - layout->addStretch(); - layout->addWidget(m_btDownload); - layout->addWidget(m_btCheckUpdate); - layout->addStretch(); + auto layout = ControlUtil::createHLayoutByWidgets({ /*stretch*/ nullptr, m_btDownload, + m_btInstall, m_btCheckUpdate, /*stretch*/ nullptr }); + layout->setSpacing(6); return layout; } @@ -110,17 +117,17 @@ QLayout *AboutPage::setupButtonsLayout() void AboutPage::setupNewVersionUpdate() { const auto refreshNewVersion = [&] { - auto updateChecker = taskManager()->taskInfoUpdateChecker(); - m_isNewVersion = updateChecker->isNewVersion(); + auto taskInfo = taskManager()->taskInfoUpdateChecker(); + + m_isNewVersion = taskInfo->isNewVersion(); m_labelArea->setVisible(m_isNewVersion); - m_labelRelease->setText(updateChecker->releaseText()); + m_labelRelease->setText(taskInfo->releaseText()); - m_btDownload->setVisible(m_isNewVersion); - m_btDownload->setWindowFilePath(updateChecker->downloadUrl()); - m_btDownload->setToolTip(updateChecker->downloadUrl()); + m_progressBar->setRange(0, taskInfo->downloadSize()); + m_btDownload->setVisible(m_isNewVersion && !m_btInstall->isVisible()); - m_btCheckUpdate->setToolTip(checkUpdateToolTip(updateChecker)); + m_btCheckUpdate->setToolTip(checkUpdateToolTip(taskInfo)); retranslateNewVersionBox(); }; @@ -129,3 +136,28 @@ void AboutPage::setupNewVersionUpdate() connect(taskManager(), &TaskManager::appVersionUpdated, this, refreshNewVersion); } + +void AboutPage::setupAutoUpdate() +{ + const auto refreshAutoUpdate = [&] { + auto manager = autoUpdateManager(); + + const bool isNewVersion = manager->isNewVersion(); + const bool isDownloaded = manager->isDownloaded(); + const bool isDownloadActive = (manager->isDownloading() || isDownloaded); + + if (isDownloaded) { + m_progressBar->setValue(m_progressBar->maximum()); + } + m_progressBar->setVisible(isDownloadActive); + + m_btDownload->setVisible(isNewVersion && !isDownloadActive); + m_btInstall->setVisible(isNewVersion && isDownloaded); + }; + + refreshAutoUpdate(); + + connect(autoUpdateManager(), &AutoUpdateManager::isDownloadingChanged, this, refreshAutoUpdate); + connect(autoUpdateManager(), &AutoUpdateManager::bytesReceivedChanged, m_progressBar, + &QProgressBar::setValue); +} diff --git a/src/ui/form/home/pages/aboutpage.h b/src/ui/form/home/pages/aboutpage.h index f96e6d3a..c6a1cb2e 100644 --- a/src/ui/form/home/pages/aboutpage.h +++ b/src/ui/form/home/pages/aboutpage.h @@ -20,6 +20,7 @@ private: void setupNewVersionBox(); QLayout *setupButtonsLayout(); void setupNewVersionUpdate(); + void setupAutoUpdate(); private: bool m_isNewVersion = false; @@ -27,7 +28,9 @@ private: QGroupBox *m_gbNewVersion = nullptr; QLabel *m_labelRelease = nullptr; QWidget *m_labelArea = nullptr; + QProgressBar *m_progressBar = nullptr; QToolButton *m_btDownload = nullptr; + QToolButton *m_btInstall = nullptr; QToolButton *m_btCheckUpdate = nullptr; }; diff --git a/src/ui/form/home/pages/homebasepage.cpp b/src/ui/form/home/pages/homebasepage.cpp index 712d089b..1af6a231 100644 --- a/src/ui/form/home/pages/homebasepage.cpp +++ b/src/ui/form/home/pages/homebasepage.cpp @@ -40,6 +40,11 @@ DriverManager *HomeBasePage::driverManager() const return ctrl()->driverManager(); } +AutoUpdateManager *HomeBasePage::autoUpdateManager() const +{ + return ctrl()->autoUpdateManager(); +} + TaskManager *HomeBasePage::taskManager() const { return ctrl()->taskManager(); diff --git a/src/ui/form/home/pages/homebasepage.h b/src/ui/form/home/pages/homebasepage.h index 2653a883..8de85da7 100644 --- a/src/ui/form/home/pages/homebasepage.h +++ b/src/ui/form/home/pages/homebasepage.h @@ -10,16 +10,18 @@ QT_FORWARD_DECLARE_CLASS(QGroupBox) QT_FORWARD_DECLARE_CLASS(QLabel) QT_FORWARD_DECLARE_CLASS(QLineEdit) QT_FORWARD_DECLARE_CLASS(QMenu) +QT_FORWARD_DECLARE_CLASS(QProgressBar) QT_FORWARD_DECLARE_CLASS(QPushButton) QT_FORWARD_DECLARE_CLASS(QToolButton) +class AutoUpdateManager; class ConfManager; class DriverManager; class FirewallConf; class FortManager; class FortSettings ; -class IniUser; class HomeController; +class IniUser; class TaskManager; class TranslationManager; class WindowManager; @@ -39,6 +41,7 @@ protected: FirewallConf *conf() const; IniUser *iniUser() const; DriverManager *driverManager() const; + AutoUpdateManager *autoUpdateManager() const; TaskManager *taskManager() const; TranslationManager *translationManager() const; WindowManager *windowManager() const; diff --git a/src/ui/manager/autoupdatemanager.cpp b/src/ui/manager/autoupdatemanager.cpp index 8c6313f3..f0a3a4f0 100644 --- a/src/ui/manager/autoupdatemanager.cpp +++ b/src/ui/manager/autoupdatemanager.cpp @@ -16,9 +16,12 @@ AutoUpdateManager::AutoUpdateManager(const QString &cachePath, QObject *parent) { } -bool AutoUpdateManager::isDownloading() const +void AutoUpdateManager::setIsDownloading(bool v) { - return downloader() && downloader()->started(); + if (m_isDownloading != v) { + m_isDownloading = v; + emit isDownloadingChanged(v); + } } int AutoUpdateManager::bytesReceived() const @@ -31,7 +34,7 @@ void AutoUpdateManager::setUp() auto taskManager = IoCDependency(); auto taskInfo = taskManager->taskInfoUpdateChecker(); - connect(taskManager, &TaskManager::appVersionDownloaded, this, + connect(taskManager, &TaskManager::appVersionUpdated, this, [=, this] { setupByTaskInfo(taskInfo); }); setupByTaskInfo(taskInfo); @@ -58,37 +61,43 @@ bool AutoUpdateManager::startDownload() void AutoUpdateManager::setupDownloader() { - setIsDownloaded(false); - downloader()->setUrl(m_downloadUrl); - connect(downloader(), &NetDownloader::startedChanged, this, - &AutoUpdateManager::isDownloadingChanged); connect(downloader(), &NetDownloader::dataReceived, this, &AutoUpdateManager::bytesReceivedChanged); + + setIsDownloaded(false); + setIsDownloading(true); } -void AutoUpdateManager::downloadFinished(bool success) +void AutoUpdateManager::downloadFinished(const QByteArray &data, bool success) { if (success) { - success = saveInstaller(); + success = saveInstaller(data); + setIsDownloaded(success); } + setIsDownloading(false); + finish(success); } void AutoUpdateManager::setupByTaskInfo(TaskInfoUpdateChecker *taskInfo) { + m_isNewVersion = taskInfo->isNewVersion(); + if (!m_isNewVersion) + return; + m_downloadUrl = taskInfo->downloadUrl(); - if (m_downloadUrl.isEmpty()) + m_downloadSize = taskInfo->downloadSize(); + if (m_downloadUrl.isEmpty() || m_downloadSize <= 0) return; m_fileName = QUrl(m_downloadUrl).fileName(); - m_downloadSize = taskInfo->downloadSize(); const QFileInfo fi(installerPath()); - setIsDownloaded(fi.size() == m_downloadSize); + setIsDownloaded(fi.exists() && fi.size() == m_downloadSize); } void AutoUpdateManager::clearUpdateDir() @@ -100,9 +109,8 @@ void AutoUpdateManager::clearUpdateDir() } } -bool AutoUpdateManager::saveInstaller() +bool AutoUpdateManager::saveInstaller(const QByteArray &fileData) { - const QByteArray fileData = downloader()->takeBuffer(); if (fileData.size() != m_downloadSize) return false; diff --git a/src/ui/manager/autoupdatemanager.h b/src/ui/manager/autoupdatemanager.h index 5ef7a53f..bc627bab 100644 --- a/src/ui/manager/autoupdatemanager.h +++ b/src/ui/manager/autoupdatemanager.h @@ -15,9 +15,14 @@ class AutoUpdateManager : public TaskDownloader, public IocService public: explicit AutoUpdateManager(const QString &cachePath, QObject *parent = nullptr); - bool isDownloaded() const { return m_isDownloaded; } + bool isNewVersion() const { return m_isNewVersion; } + + bool isDownloaded() const { return m_isDownloaded; } + void setIsDownloaded(bool v) { m_isDownloaded = v; } + + bool isDownloading() const { return m_isDownloading; } + void setIsDownloading(bool v); - virtual bool isDownloading() const; virtual int bytesReceived() const; void setUp() override; @@ -29,32 +34,32 @@ public slots: bool runInstaller(); signals: - void isDownloadingChanged(); - void bytesReceivedChanged(); + void isDownloadingChanged(bool downloading); + void bytesReceivedChanged(int size); void restartClients(); protected: - void setIsDownloaded(bool v) { m_isDownloaded = v; } - void setupDownloader() override; protected slots: - void downloadFinished(bool success) override; + void downloadFinished(const QByteArray &data, bool success) override; private: void setupByTaskInfo(TaskInfoUpdateChecker *taskInfo); void clearUpdateDir(); - bool saveInstaller(); + bool saveInstaller(const QByteArray &fileData); QString installerPath() const { return m_updatePath + m_fileName; } static QString getDownloadUrl(); private: - bool m_isDownloaded = false; + bool m_isNewVersion : 1 = false; + bool m_isDownloaded : 1 = false; + bool m_isDownloading : 1 = false; QString m_updatePath; diff --git a/src/ui/rpc/autoupdatemanagerrpc.cpp b/src/ui/rpc/autoupdatemanagerrpc.cpp index 5376b950..c3f4d919 100644 --- a/src/ui/rpc/autoupdatemanagerrpc.cpp +++ b/src/ui/rpc/autoupdatemanagerrpc.cpp @@ -55,19 +55,11 @@ AutoUpdateManagerRpc::AutoUpdateManagerRpc(const QString &cachePath, QObject *pa { } -void AutoUpdateManagerRpc::setIsDownloading(bool v) -{ - if (m_isDownloading != v) { - m_isDownloading = v; - emit isDownloadingChanged(); - } -} - void AutoUpdateManagerRpc::setBytesReceived(int v) { if (m_bytesReceived != v) { m_bytesReceived = v; - emit bytesReceivedChanged(); + emit bytesReceivedChanged(v); } } diff --git a/src/ui/rpc/autoupdatemanagerrpc.h b/src/ui/rpc/autoupdatemanagerrpc.h index e26116ef..f3b7e6c6 100644 --- a/src/ui/rpc/autoupdatemanagerrpc.h +++ b/src/ui/rpc/autoupdatemanagerrpc.h @@ -15,9 +15,6 @@ class AutoUpdateManagerRpc : public AutoUpdateManager public: explicit AutoUpdateManagerRpc(const QString &cachePath, QObject *parent = nullptr); - bool isDownloading() const override { return m_isDownloading; } - void setIsDownloading(bool v); - int bytesReceived() const override { return m_bytesReceived; } void setBytesReceived(int v); @@ -41,7 +38,6 @@ private: void setupClientSignals(); private: - bool m_isDownloading = false; int m_bytesReceived = 0; }; diff --git a/src/ui/task/taskdownloader.h b/src/ui/task/taskdownloader.h index c38616ee..a678c23c 100644 --- a/src/ui/task/taskdownloader.h +++ b/src/ui/task/taskdownloader.h @@ -22,7 +22,7 @@ public slots: void finish(bool success = false) override; protected slots: - virtual void downloadFinished(bool success) = 0; + virtual void downloadFinished(const QByteArray &data, bool success) = 0; private: void createDownloader(); diff --git a/src/ui/task/taskupdatechecker.cpp b/src/ui/task/taskupdatechecker.cpp index 86f3e85a..25011ff7 100644 --- a/src/ui/task/taskupdatechecker.cpp +++ b/src/ui/task/taskupdatechecker.cpp @@ -55,10 +55,10 @@ void TaskUpdateChecker::setupDownloader() downloader()->setUrl(APP_UPDATES_API_URL); } -void TaskUpdateChecker::downloadFinished(bool success) +void TaskUpdateChecker::downloadFinished(const QByteArray &data, bool success) { if (success) { - success = parseBuffer(downloader()->takeBuffer()); + success = parseBuffer(data); } finish(success); diff --git a/src/ui/task/taskupdatechecker.h b/src/ui/task/taskupdatechecker.h index 70637143..fb56c4e8 100644 --- a/src/ui/task/taskupdatechecker.h +++ b/src/ui/task/taskupdatechecker.h @@ -20,7 +20,7 @@ protected: void setupDownloader() override; protected slots: - void downloadFinished(bool success) override; + void downloadFinished(const QByteArray &data, bool success) override; private: bool parseBuffer(const QByteArray &buffer); diff --git a/src/ui/task/taskzonedownloader.cpp b/src/ui/task/taskzonedownloader.cpp index a3581cc3..dd82bb12 100644 --- a/src/ui/task/taskzonedownloader.cpp +++ b/src/ui/task/taskzonedownloader.cpp @@ -34,13 +34,13 @@ void TaskZoneDownloader::setupDownloader() downloader()->setData(formData().toUtf8()); } -void TaskZoneDownloader::downloadFinished(bool success) +void TaskZoneDownloader::downloadFinished(const QByteArray &data, bool success) { if (success) { success = false; QString textChecksum; - const auto text = QString::fromLatin1(downloader()->takeBuffer()); + const auto text = QString::fromLatin1(data); const auto list = parseAddresses(text, textChecksum); if (!list.isEmpty() @@ -57,25 +57,25 @@ void TaskZoneDownloader::downloadFinished(bool success) void TaskZoneDownloader::loadTextInline() { - downloader()->setBuffer(textInline().toUtf8()); + const QByteArray data = textInline().toUtf8(); - downloadFinished(/*success=*/true); + downloadFinished(data, /*success=*/true); } void TaskZoneDownloader::loadLocalFile() { + QByteArray data; bool success = false; const auto fileModTime = FileUtil::fileModTime(url()); if (sourceModTime() != fileModTime || !FileUtil::fileExists(cacheFileBinPath())) { - const auto buffer = FileUtil::readFileData(url()); - downloader()->setBuffer(buffer); + data = FileUtil::readFileData(url()); setSourceModTime(fileModTime); success = true; } - downloadFinished(success); + downloadFinished(data, success); } StringViewList TaskZoneDownloader::parseAddresses(const QString &text, QString &checksum) const diff --git a/src/ui/task/taskzonedownloader.h b/src/ui/task/taskzonedownloader.h index 88f4df91..5f01d592 100644 --- a/src/ui/task/taskzonedownloader.h +++ b/src/ui/task/taskzonedownloader.h @@ -75,7 +75,7 @@ protected: void setupDownloader() override; protected slots: - void downloadFinished(bool success) override; + void downloadFinished(const QByteArray &data, bool success) override; private: void loadTextInline(); diff --git a/src/ui/util/net/netdownloader.cpp b/src/ui/util/net/netdownloader.cpp index 745709d2..5590fa3d 100644 --- a/src/ui/util/net/netdownloader.cpp +++ b/src/ui/util/net/netdownloader.cpp @@ -26,14 +26,14 @@ void NetDownloader::setStarted(bool v) { if (m_started != v) { m_started = v; - emit startedChanged(); + emit startedChanged(v); } } QByteArray NetDownloader::takeBuffer() { - const QByteArray buf = m_buffer; - m_buffer.clear(); + QByteArray buf; + m_buffer.swap(buf); return buf; } @@ -81,7 +81,7 @@ void NetDownloader::finish(bool success) m_reply = nullptr; } - emit finished(success); + emit finished(takeBuffer(), success); } void NetDownloader::onDownloadProgress(qint64 bytesReceived, qint64 /*bytesTotal*/) @@ -93,8 +93,9 @@ void NetDownloader::onDownloadProgress(qint64 bytesReceived, qint64 /*bytesTotal m_buffer.append(data); - if (m_buffer.size() < DOWNLOAD_MAXSIZE) { - emit dataReceived(); + const int bufferSize = m_buffer.size(); + if (bufferSize < DOWNLOAD_MAXSIZE) { + emit dataReceived(bufferSize); } else { qCWarning(LC) << "Error: Too big file"; finish(); diff --git a/src/ui/util/net/netdownloader.h b/src/ui/util/net/netdownloader.h index 33fde47e..598aea1c 100644 --- a/src/ui/util/net/netdownloader.h +++ b/src/ui/util/net/netdownloader.h @@ -33,9 +33,9 @@ public: QByteArray takeBuffer(); signals: - void startedChanged(); - void dataReceived(); - void finished(bool success); + void startedChanged(bool started); + void dataReceived(int size); + void finished(const QByteArray &data, bool success); public slots: void start();