diff --git a/src/manager.cpp b/src/manager.cpp index 8d936f8..6095c91 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -60,7 +60,15 @@ Manager::Manager() #endif } -Manager::~Manager() = default; +Manager::~Manager() +{ + if (updateAutoChecker_ && updateAutoChecker_->isLastCheckDateChanged()) { + Settings settings; + settings.load(); + settings.lastUpdateCheck = updateAutoChecker_->lastCheckDate(); + settings.save(); + } +} void Manager::updateSettings(const Settings &settings) { @@ -71,6 +79,13 @@ void Manager::updateSettings(const Settings &settings) {"$translators$", settings.translatorsDir}, {"$tessdata$", settings.tessdataPath}, }); + if (settings.autoUpdateIntervalDays > 0) { + updateAutoChecker_ = std::make_unique(*updater_); + updateAutoChecker_->setLastCheckDate(settings.lastUpdateCheck); + updateAutoChecker_->setCheckIntervalDays(settings.autoUpdateIntervalDays); + } else { + updateAutoChecker_.reset(); + } tray_->updateSettings(settings); capturer_->updateSettings(settings); diff --git a/src/manager.h b/src/manager.h index df116e6..f0d7fd7 100644 --- a/src/manager.h +++ b/src/manager.h @@ -38,6 +38,7 @@ private: std::unique_ptr translator_; std::unique_ptr representer_; std::unique_ptr updater_; + std::unique_ptr updateAutoChecker_; TaskPtr last_; int activeTaskCount_{0}; }; diff --git a/src/service/updates.cpp b/src/service/updates.cpp index 3ae7b6c..2c95323 100644 --- a/src/service/updates.cpp +++ b/src/service/updates.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace update { @@ -672,4 +673,69 @@ QString Installer::errorString() const return errors_.join('\n'); } +AutoChecker::AutoChecker(Loader &loader, QObject *parent) + : QObject(parent) + , loader_(loader) +{ + SOFT_ASSERT(loader.model(), return ); + connect(loader.model(), &Model::modelReset, // + this, &AutoChecker::handleModelReset); +} + +AutoChecker::~AutoChecker() = default; + +bool AutoChecker::isLastCheckDateChanged() const +{ + return isLastCheckDateChanged_; +} + +QDateTime AutoChecker::lastCheckDate() const +{ + return lastCheckDate_; +} + +void AutoChecker::setCheckIntervalDays(int days) +{ + checkIntervalDays_ = days; + scheduleNextCheck(); +} + +void AutoChecker::setLastCheckDate(const QDateTime &dt) +{ + isLastCheckDateChanged_ = false; + + lastCheckDate_ = dt; + if (!lastCheckDate_.isValid()) + lastCheckDate_ = QDateTime::currentDateTime(); + + scheduleNextCheck(); +} + +void AutoChecker::scheduleNextCheck() +{ + if (checkIntervalDays_ < 1 || !lastCheckDate_.isValid()) + return; + + if (!timer_) { + timer_ = std::make_unique(); + timer_->setSingleShot(true); + connect(timer_.get(), &QTimer::timeout, // + &loader_, &Loader::checkForUpdates); + } + + auto nextTime = lastCheckDate_.addDays(checkIntervalDays_); + const auto now = QDateTime::currentDateTime(); + if (nextTime < now) + nextTime = now.addSecs(5); + + timer_->start(now.msecsTo(nextTime)); +} + +void AutoChecker::handleModelReset() +{ + lastCheckDate_ = QDateTime::currentDateTime(); + isLastCheckDateChanged_ = true; + scheduleNextCheck(); +} + } // namespace update diff --git a/src/service/updates.h b/src/service/updates.h index bd529d1..0d75bdd 100644 --- a/src/service/updates.h +++ b/src/service/updates.h @@ -133,4 +133,27 @@ private: std::unique_ptr installer_; }; +class AutoChecker : public QObject +{ + Q_OBJECT +public: + explicit AutoChecker(Loader& loader, QObject* parent = nullptr); + ~AutoChecker(); + + bool isLastCheckDateChanged() const; + QDateTime lastCheckDate() const; + void setCheckIntervalDays(int days); + void setLastCheckDate(const QDateTime& dt); + +private: + void handleModelReset(); + void scheduleNextCheck(); + + Loader& loader_; + bool isLastCheckDateChanged_{false}; + int checkIntervalDays_{0}; + QDateTime lastCheckDate_; + std::unique_ptr timer_; +}; + } // namespace update diff --git a/src/settings.cpp b/src/settings.cpp index 7139ff0..e9e9e63 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -150,7 +150,8 @@ void Settings::save() const settings.remove(qs_proxyPassword); } - settings.setValue(qs_autoUpdateType, int(autoUpdateType)); + settings.setValue(qs_autoUpdateType, autoUpdateIntervalDays); + settings.setValue(qs_lastUpdateCheck, lastUpdateCheck); settings.endGroup(); @@ -215,9 +216,10 @@ void Settings::load() settings.value(qs_proxySavePassword, proxySavePassword).toBool(); proxyPassword = shuffle(settings.value(qs_proxyPassword).toString()); - autoUpdateType = AutoUpdate( - std::clamp(settings.value(qs_autoUpdateType, int(autoUpdateType)).toInt(), - int(AutoUpdate::Disabled), int(AutoUpdate::Monthly))); + autoUpdateIntervalDays = + settings.value(qs_autoUpdateType, autoUpdateIntervalDays).toInt(); + lastUpdateCheck = + settings.value(qs_lastUpdateCheck, lastUpdateCheck).toDateTime(); settings.endGroup(); diff --git a/src/settings.h b/src/settings.h index 65f4532..1a52be0 100644 --- a/src/settings.h +++ b/src/settings.h @@ -2,6 +2,7 @@ #include "stfwd.h" +#include #include #include @@ -16,8 +17,6 @@ using Substitutions = std::unordered_multimap; enum class ProxyType { Disabled, System, Socks5, Http }; -enum class AutoUpdate { Disabled, Daily, Weekly, Monthly }; - class Settings { public: @@ -41,8 +40,8 @@ public: QString proxyPassword; bool proxySavePassword{false}; - AutoUpdate autoUpdateType{AutoUpdate::Disabled}; - QString lastUpdateCheck{""}; + int autoUpdateIntervalDays{0}; + QDateTime lastUpdateCheck; Substitutions userSubstitutions; bool useUserSubstitutions{true}; diff --git a/src/settingseditor.cpp b/src/settingseditor.cpp index 7c4010d..51ff595 100644 --- a/src/settingseditor.cpp +++ b/src/settingseditor.cpp @@ -59,13 +59,6 @@ SettingsEditor::SettingsEditor(Manager &manager, update::Loader &updater) updateTranslationLanguages(); // updates - QMap updateTypes; - updateTypes.insert(AutoUpdate::Disabled, tr("Disabled")); - updateTypes.insert(AutoUpdate::Daily, tr("Daily")); - updateTypes.insert(AutoUpdate::Weekly, tr("Weekly")); - updateTypes.insert(AutoUpdate::Monthly, tr("Monthly")); - ui->updateCombo->addItems(updateTypes.values()); - auto updatesProxy = new QSortFilterProxyModel(this); updatesProxy->setSourceModel(updater_.model()); ui->updatesView->setModel(updatesProxy); @@ -136,6 +129,9 @@ Settings SettingsEditor::settings() const settings.resultShowType = ui->trayRadio->isChecked() ? ResultMode::Tooltip : ResultMode::Widget; + + settings.autoUpdateIntervalDays = ui->autoUpdateInterval->value(); + return settings; } @@ -179,6 +175,8 @@ void SettingsEditor::setSettings(const Settings &settings) ui->trayRadio->setChecked(settings.resultShowType == ResultMode::Tooltip); ui->dialogRadio->setChecked(settings.resultShowType == ResultMode::Widget); + + ui->autoUpdateInterval->setValue(settings.autoUpdateIntervalDays); } void SettingsEditor::updateCurrentPage() diff --git a/src/settingseditor.ui b/src/settingseditor.ui index 53d283e..dfd3944 100644 --- a/src/settingseditor.ui +++ b/src/settingseditor.ui @@ -485,12 +485,19 @@ - Check for updates: + Update check interval (days): - + + + 0 - disabled + + + 360 + + diff --git a/src/stfwd.h b/src/stfwd.h index 9f72f0d..a437494 100644 --- a/src/stfwd.h +++ b/src/stfwd.h @@ -19,7 +19,8 @@ class Recognizer; namespace update { class Loader; -} +class AutoChecker; +} // namespace update using TaskPtr = std::shared_ptr; using LanguageId = QString;