From 3fed97ad864eeae486571f0d12ac06a34147b696 Mon Sep 17 00:00:00 2001
From: optizone <42874998+optizone@users.noreply.github.com>
Date: Sat, 9 Mar 2019 16:11:39 +0300
Subject: [PATCH] Auto update check (#1235)
* init commit
* bug fix
* call slot of null object bug fix
* delete extra disconnect() func
* change api and add doc
* run astyle
* some improvements
* memory leak fix
* add check on start checkbox
* add checkbox to about page
* serve version check reply using lambda instead of slot
* fix grammar mistakes
* more docs
* save some lines
* change button text
* astyle
* change message text
* dont use QApplication pointer as a parent for network manager
* proper deletion of QNetworkReply*
* VersionChecker -> UpdateWorker
* windows dll hack
* after rebase fix
* some improvements
* better determination of arch
* more docs
* improvements
* add UpdateWorker::showUpdateDialog
* remove odd condition
* more improvements
* fix windows bug
* make dialog non-blocking
* change text in download progress dialog
* bug fix
* remove debug conditions
* change docs format
---
src/Cutter.pro | 4 +-
src/CutterApplication.cpp | 11 ++
src/Main.cpp | 14 +++
src/common/Configuration.cpp | 10 ++
src/common/Configuration.h | 6 +-
src/common/UpdateWorker.cpp | 211 ++++++++++++++++++++++++++++++++++
src/common/UpdateWorker.h | 123 ++++++++++++++++++++
src/dialogs/AboutDialog.cpp | 102 ++++++----------
src/dialogs/AboutDialog.h | 14 ++-
src/dialogs/AboutDialog.ui | 13 +++
src/dialogs/WelcomeDialog.cpp | 10 +-
src/dialogs/WelcomeDialog.h | 1 +
src/dialogs/WelcomeDialog.ui | 168 ++++++++++++++++-----------
13 files changed, 550 insertions(+), 137 deletions(-)
create mode 100644 src/common/UpdateWorker.cpp
create mode 100644 src/common/UpdateWorker.h
diff --git a/src/Cutter.pro b/src/Cutter.pro
index 86c85454..d5f5e2f0 100644
--- a/src/Cutter.pro
+++ b/src/Cutter.pro
@@ -312,7 +312,8 @@ SOURCES += \
common/PythonManager.cpp \
plugins/PluginManager.cpp \
common/BasicBlockHighlighter.cpp \
- dialogs/LinkTypeDialog.cpp
+ dialogs/LinkTypeDialog.cpp \
+ common/UpdateWorker.cpp
HEADERS += \
core/Cutter.h \
@@ -429,6 +430,7 @@ HEADERS += \
common/PythonManager.h \
plugins/PluginManager.h \
common/BasicBlockHighlighter.h \
+ common/UpdateWorker.h \
dialogs/LinkTypeDialog.h
FORMS += \
diff --git a/src/CutterApplication.cpp b/src/CutterApplication.cpp
index 50298c17..cb4f8d4d 100644
--- a/src/CutterApplication.cpp
+++ b/src/CutterApplication.cpp
@@ -23,6 +23,10 @@
#include
+#ifdef Q_OS_WIN
+#include
+#endif // Q_OS_WIN
+
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv)
{
// Setup application information
@@ -32,6 +36,13 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
setLayoutDirection(Qt::LeftToRight);
// WARN!!! Put initialization code below this line. Code above this line is mandatory to be run First
+
+#ifdef Q_OS_WIN
+ // Hack to force Cutter load internet connection related DLL's
+ QSslSocket s;
+ s.sslConfiguration();
+#endif // Q_OS_WIN
+
// Load translations
if (!loadTranslations()) {
qWarning() << "Cannot load translations";
diff --git a/src/Main.cpp b/src/Main.cpp
index 62e23575..564d7a25 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -1,6 +1,8 @@
#include "CutterApplication.h"
#include "core/MainWindow.h"
+#include "common/UpdateWorker.h"
+#include "CutterConfig.h"
/**
* @brief Migrate Settings used before Cutter 1.8
@@ -34,6 +36,18 @@ int main(int argc, char *argv[])
CutterApplication a(argc, argv);
+ if (Config()->getAutoUpdateEnabled()) {
+ UpdateWorker *updateWorker = new UpdateWorker;
+ QObject::connect(updateWorker, &UpdateWorker::checkComplete,
+ [=](const QString & version, const QString & error) {
+ if (error == "" && version != CUTTER_VERSION_FULL) {
+ updateWorker->showUpdateDialog(true);
+ }
+ updateWorker->deleteLater();
+ });
+ updateWorker->checkCurrentVersion(7000);
+ }
+
int ret = a.exec();
return ret;
diff --git a/src/common/Configuration.cpp b/src/common/Configuration.cpp
index 0977d469..f1d27e3a 100644
--- a/src/common/Configuration.cpp
+++ b/src/common/Configuration.cpp
@@ -136,6 +136,16 @@ void Configuration::resetAll()
emit fontsUpdated();
}
+bool Configuration::getAutoUpdateEnabled() const
+{
+ return s.value("autoUpdateEnabled", false).toBool();
+}
+
+void Configuration::setAutoUpdateEnabled(bool au)
+{
+ s.setValue("autoUpdateEnabled", au);
+}
+
/**
* @brief get the current Locale set in Cutter's user configuration
* @return a QLocale object describes user's current locale
diff --git a/src/common/Configuration.h b/src/common/Configuration.h
index e7a9296b..3e48748e 100644
--- a/src/common/Configuration.h
+++ b/src/common/Configuration.h
@@ -46,6 +46,10 @@ public:
void resetAll();
+ // Auto update
+ bool getAutoUpdateEnabled() const;
+ void setAutoUpdateEnabled(bool au);
+
// Languages
QLocale getCurrLocale() const;
void setLocale(const QLocale &l);
@@ -58,7 +62,7 @@ public:
// Colors
bool windowColorIsDark();
- void setLastThemeOf(const CutterQtTheme &currQtTheme, const QString& theme);
+ void setLastThemeOf(const CutterQtTheme &currQtTheme, const QString &theme);
QString getLastThemeOf(const CutterQtTheme &currQtTheme) const;
const QColor getColor(const QString &name) const;
void setTheme(int theme);
diff --git a/src/common/UpdateWorker.cpp b/src/common/UpdateWorker.cpp
new file mode 100644
index 00000000..816bec0f
--- /dev/null
+++ b/src/common/UpdateWorker.cpp
@@ -0,0 +1,211 @@
+#include "UpdateWorker.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include "common/Configuration.h"
+#include "CutterConfig.h"
+
+UpdateWorker::UpdateWorker(QObject *parent) :
+ QObject(parent), latestVersion(""), pending(false)
+{
+ connect(&t, &QTimer::timeout, [this]() {
+ if (pending) {
+ disconnect(checkReply, nullptr, this, nullptr);
+ checkReply->close();
+ checkReply->deleteLater();
+ emit checkComplete("", tr("Time limit exceeded during version check. Please check your "
+ "internet connection and try again."));
+ }
+ });
+}
+
+void UpdateWorker::checkCurrentVersion(time_t timeoutMs)
+{
+ QUrl url("https://api.github.com/repos/radareorg/cutter/releases/latest");
+ QNetworkRequest request;
+ request.setUrl(url);
+
+ t.setInterval(timeoutMs);
+ t.setSingleShot(true);
+ t.start();
+
+ checkReply = nm.get(request);
+ connect(checkReply, &QNetworkReply::finished,
+ this, &UpdateWorker::serveVersionCheckReply);
+ pending = true;
+}
+
+void UpdateWorker::download(QString filename, QString version)
+{
+ downloadFile.setFileName(filename);
+ downloadFile.open(QIODevice::WriteOnly);
+
+ QNetworkRequest request;
+ request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
+ QUrl url(QString("https://github.com/radareorg/cutter/releases/"
+ "download/v%1/%2").arg(version).arg(getRepositoryFileName()));
+ request.setUrl(url);
+
+ downloadReply = nm.get(request);
+ connect(downloadReply, &QNetworkReply::downloadProgress,
+ this, &UpdateWorker::process);
+ connect(downloadReply, &QNetworkReply::finished,
+ this, &UpdateWorker::serveDownloadFinish);
+}
+
+void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
+{
+ QMessageBox mb;
+ mb.setWindowTitle(tr("Version control"));
+ mb.setText(tr("There is an update available for Cutter.
")
+ + "" + tr("Current version:") + " " CUTTER_VERSION_FULL "
"
+ + "" + tr("Latest version:") + " " + latestVersion + "
"
+ + tr("For update, please check the link:
")
+ + QString(""
+ "https://github.com/radareorg/cutter/releases/tag/v%1
").arg(latestVersion)
+ + tr("or click \"Download\" to download latest version of Cutter."));
+ if (showDontCheckForUpdatesButton) {
+ mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok);
+ mb.button(QMessageBox::Reset)->setText(tr("Don't check for updates"));
+ } else {
+ mb.setStandardButtons(QMessageBox::Save | QMessageBox::Ok);
+ }
+ mb.button(QMessageBox::Save)->setText(tr("Download"));
+ mb.setDefaultButton(QMessageBox::Ok);
+ int ret = mb.exec();
+ if (ret == QMessageBox::Reset) {
+ Config()->setAutoUpdateEnabled(false);
+ } else if (ret == QMessageBox::Save) {
+ QString fullFileName =
+ QFileDialog::getSaveFileName(nullptr,
+ tr("Choose directory for downloading"),
+ QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +
+ QDir::separator() + getRepositoryFileName(),
+ QString("%1 (*.%1)").arg(getRepositeryExt()));
+ if (fullFileName != "") {
+ QProgressDialog progressDial(tr("Downloading update..."),
+ tr("Cancel"),
+ 0, 100);
+ connect(this, &UpdateWorker::downloadProcess,
+ [&progressDial](size_t curr, size_t total) {
+ progressDial.setValue(100.0f * curr / total);
+ });
+ connect(&progressDial, &QProgressDialog::canceled,
+ this, &UpdateWorker::abortDownload);
+ connect(this, &UpdateWorker::downloadFinished,
+ &progressDial, &QProgressDialog::cancel);
+ connect(this, &UpdateWorker::downloadFinished,
+ [](QString filePath){
+ QMessageBox info(QMessageBox::Information,
+ tr("Download finished!"),
+ tr("Latest version of Cutter was succesfully downloaded!"),
+ QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok,
+ nullptr);
+ info.button(QMessageBox::Open)->setText(tr("Open file"));
+ info.button(QMessageBox::Yes)->setText(tr("Open download folder"));
+ int r = info.exec();
+ if (r == QMessageBox::Open) {
+ QDesktopServices::openUrl(filePath);
+ } else if (r == QMessageBox::Yes) {
+ auto path = filePath.split('/');
+ path.removeLast();
+ QDesktopServices::openUrl(path.join('/'));
+ }
+ });
+ download(fullFileName, latestVersion);
+ // Calling show() before exec() is only way make dialog non-modal
+ // it seems wierd, but it works
+ progressDial.show();
+ progressDial.exec();
+ }
+ }
+}
+
+void UpdateWorker::abortDownload()
+{
+ disconnect(downloadReply, &QNetworkReply::finished,
+ this, &UpdateWorker::serveDownloadFinish);
+ disconnect(downloadReply, &QNetworkReply::downloadProgress,
+ this, &UpdateWorker::process);
+ downloadReply->close();
+ downloadReply->deleteLater();
+ downloadFile.remove();
+}
+
+void UpdateWorker::serveVersionCheckReply()
+{
+ pending = false;
+ QString versionReply = "";
+ QString errStr = "";
+ if (checkReply->error()) {
+ errStr = checkReply->errorString();
+ } else {
+ versionReply = QJsonDocument::fromJson(checkReply->readAll()).object().value("tag_name").toString();
+ versionReply.remove('v');
+ }
+ latestVersion = versionReply;
+ checkReply->close();
+ checkReply->deleteLater();
+ emit checkComplete(versionReply, errStr);
+}
+
+void UpdateWorker::serveDownloadFinish()
+{
+ downloadReply->close();
+ downloadReply->deleteLater();
+ if (downloadReply->error()) {
+ emit downloadError(downloadReply->errorString());
+ } else {
+ emit downloadFinished(downloadFile.fileName());
+ }
+}
+
+void UpdateWorker::process(size_t bytesReceived, size_t bytesTotal)
+{
+ downloadFile.write(downloadReply->readAll());
+ emit downloadProcess(bytesReceived, bytesTotal);
+}
+
+QString UpdateWorker::getRepositeryExt() const
+{
+#ifdef Q_OS_LINUX
+ return "AppImage";
+#elif defined (Q_OS_WIN64) || defined (Q_OS_WIN32)
+ return "zip";
+#elif defined (Q_OS_MACOS)
+ return "dmg";
+#endif
+}
+
+QString UpdateWorker::getRepositoryFileName() const
+{
+ QString downloadFileName;
+#ifdef Q_OS_LINUX
+ downloadFileName = "Cutter-v%1-x%2.Linux.AppImage";
+#elif defined (Q_OS_WIN64) || defined (Q_OS_WIN32)
+ downloadFileName = "Cutter-v%1-x%2.Windows.zip";
+#elif defined (Q_OS_MACOS)
+ downloadFileName = "Cutter-v%1-x%2.macOS.dmg";
+#endif
+ downloadFileName = downloadFileName
+ .arg(latestVersion)
+ .arg(QSysInfo::buildAbi().split('-').at(2).contains("64")
+ ? "64"
+ : "32");
+
+ return downloadFileName;
+}
diff --git a/src/common/UpdateWorker.h b/src/common/UpdateWorker.h
new file mode 100644
index 00000000..54790199
--- /dev/null
+++ b/src/common/UpdateWorker.h
@@ -0,0 +1,123 @@
+#ifndef UPDATEWORKER_H
+#define UPDATEWORKER_H
+
+#include
+#include
+#include
+#include
+
+class QNetworkReply;
+
+/**
+ * @class UpdateWorker
+ * @brief The UpdateWorker class is a class providing API to check for current Cutter version
+ * and download specific version of one.
+ */
+
+class UpdateWorker : public QObject
+{
+ Q_OBJECT
+public:
+ explicit UpdateWorker(QObject *parent = nullptr);
+
+ /**
+ * @fn void UpdateWorker::checkCurrentVersion(time_t timeoutMs)
+ *
+ * Sends request to determine current version of Cutter.
+ * If there is no response in @a timeoutMs milliseconds, emits
+ * @fn UpdateWorker::checkComplete(const QString& currVerson, const QString& errorMsg)
+ * with timeout error message.
+ *
+ *
+ * @sa checkComplete(const QString& verson, const QString& errorMsg)
+ */
+
+ void checkCurrentVersion(time_t timeoutMs);
+
+ /**
+ * @fn void UpdateWorker::download(QDir downloadPath, QString version)
+ *
+ * @brief Downloads provided @a version of Cutter into @a downloadDir.
+ *
+ * @sa downloadProcess(size_t bytesReceived, size_t bytesTotal)
+ */
+ void download(QString filename, QString version);
+
+ /**
+ * @fn void UpdateWorker::showUpdateDialog()
+ *
+ * Shows dialog that allows user to either download latest version of Cutter from website
+ * or download it by clicking on a button. This dialog also has "Don't check for updates"
+ * button which disables on-start update checks if @a showDontCheckForUpdatesButton is true.
+ *
+ * @sa downloadProcess(size_t bytesReceived, size_t bytesTotal)
+ */
+ void showUpdateDialog(bool showDontCheckForUpdatesButton);
+
+public slots:
+ /**
+ * @fn void UpdateWorker::abortDownload()
+ *
+ * @brief Stops current process of downloading.
+ *
+ * @note UpdateWorker::downloadFinished(QString filename) is not send after this function.
+ *
+ * @sa download(QDir downloadDir, QString version)
+ */
+ void abortDownload();
+
+signals:
+ /**
+ * @fn UpdateWorker::checkComplete(const QString& verson, const QString& errorMsg)
+ *
+ * The signal is emitted when check has been done with an empty @a errorMsg string.
+ * In case of an error @a currVerson is empty and @a errorMsg contains description
+ * of error.
+ */
+ void checkComplete(const QString &currVerson, const QString &errorMsg);
+
+ /**
+ * @fn UpdateWorker::downloadProcess(size_t bytesReceived, size_t bytesTotal)
+ *
+ * The signal is emitted each time when some amount of bytes was downloaded.
+ * May be used as indicator of download progress.
+ */
+ void downloadProcess(size_t bytesReceived, size_t bytesTotal);
+
+
+ /**
+ * @fn UpdateWorker::downloadFinished(QString filename)
+ *
+ * @brief The signal is emitted as soon as downloading completes.
+ */
+ void downloadFinished(QString filename);
+
+ /**
+ * @fn UpdateWorker::downloadError(QString errorStr)
+ *
+ * @brief The signal is emitted when error occures during download.
+ */
+ void downloadError(QString errorStr);
+
+private slots:
+ void serveVersionCheckReply();
+
+ void serveDownloadFinish();
+
+ void process(size_t bytesReceived, size_t bytesTotal);
+
+private:
+ QString getRepositeryExt() const;
+ QString getRepositoryFileName() const;
+
+private:
+ QNetworkAccessManager nm;
+ QString latestVersion;
+ QTimer t;
+ bool pending;
+ QFile downloadFile;
+ QNetworkReply *downloadReply;
+ QNetworkReply *checkReply;
+};
+
+#endif // UPDATEWORKER_H
diff --git a/src/dialogs/AboutDialog.cpp b/src/dialogs/AboutDialog.cpp
index e8d52069..9a9e49a4 100644
--- a/src/dialogs/AboutDialog.cpp
+++ b/src/dialogs/AboutDialog.cpp
@@ -8,9 +8,11 @@
#include
#include
+#include
#include
#include
#include
+#include
#include
#include
@@ -25,29 +27,32 @@ AboutDialog::AboutDialog(QWidget *parent) :
ui->logoSvgWidget->load(Config()->getLogoFile());
QString aboutString("Cutter
"
- + tr("Version") + " " CUTTER_VERSION_FULL "
"
- + tr("Using r2-") + R2_GITTAP
- + "" + tr("Optional Features:") + "
"
- + QString("Jupyter: %1
").arg(
+ + tr("Version") + " " CUTTER_VERSION_FULL "
"
+ + tr("Using r2-") + R2_GITTAP
+ + "
" + tr("Optional Features:") + "
"
+ + QString("Jupyter: %1
").arg(
#ifdef CUTTER_ENABLE_JUPYTER
- "ON"
+ "ON"
#else
- "OFF"
+ "OFF"
#endif
- )
- + QString("QtWebEngine: %2
").arg(
+ )
+ + QString("QtWebEngine: %2
").arg(
#ifdef CUTTER_ENABLE_QTWEBENGINE
- "ON"
+ "ON"
#else
- "OFF"
+ "OFF"
#endif
- )
- + "" + tr("License") + "
"
- + tr("This Software is released under the GNU General Public License v3.0")
- + "" + tr("Authors") + "
"
- "xarkes, thestr4ng3r, ballessay
"
- "Based on work by Hugo Teso <hugo.teso@gmail.org> (originally Iaito).");
+ )
+ + "" + tr("License") + "
"
+ + tr("This Software is released under the GNU General Public License v3.0")
+ + "" + tr("Authors") + "
"
+ "xarkes, thestr4ng3r, ballessay
"
+ "Based on work by Hugo Teso <hugo.teso@gmail.org> (originally Iaito).");
ui->label->setText(aboutString);
+
+ QSignalBlocker s(ui->updatesCheckBox);
+ ui->updatesCheckBox->setChecked(Config()->getAutoUpdateEnabled());
}
AboutDialog::~AboutDialog() {}
@@ -75,9 +80,7 @@ void AboutDialog::on_showPluginsButton_clicked()
void AboutDialog::on_checkForUpdatesButton_clicked()
{
- QUrl url("https://api.github.com/repos/radareorg/cutter/releases/latest");
- QNetworkRequest request;
- request.setUrl(url);
+ UpdateWorker updateWorker;
QProgressDialog waitDialog;
QProgressBar *bar = new QProgressBar(&waitDialog);
@@ -86,56 +89,25 @@ void AboutDialog::on_checkForUpdatesButton_clicked()
waitDialog.setBar(bar);
waitDialog.setLabel(new QLabel(tr("Checking for updates..."), &waitDialog));
- QNetworkAccessManager nm;
-
- QTimer timeoutTimer;
- timeoutTimer.setSingleShot(true);
- timeoutTimer.setInterval(7000);
-
- connect(&nm, &QNetworkAccessManager::finished, &timeoutTimer, &QTimer::stop);
- connect(&nm, &QNetworkAccessManager::finished, &waitDialog, &QProgressDialog::cancel);
- connect(&nm, &QNetworkAccessManager::finished, this, &AboutDialog::serveVersionCheckReply);
-
- QNetworkReply *reply = nm.get(request);
- timeoutTimer.start();
-
- connect(&timeoutTimer, &QTimer::timeout, []() {
- QMessageBox mb;
- mb.setIcon(QMessageBox::Critical);
- mb.setStandardButtons(QMessageBox::Ok);
- mb.setWindowTitle(tr("Timeout error!"));
- mb.setText(tr("Please check your internet connection and try again."));
- mb.exec();
+ connect(&updateWorker, &UpdateWorker::checkComplete, &waitDialog, &QProgressDialog::cancel);
+ connect(&updateWorker, &UpdateWorker::checkComplete,
+ [&updateWorker](const QString & version, const QString & error) {
+ if (error != "") {
+ QMessageBox::critical(nullptr, tr("Error!"), error);
+ } else {
+ if (version == CUTTER_VERSION_FULL) {
+ QMessageBox::information(nullptr, tr("Version control"), tr("Cutter is up to date!"));
+ } else {
+ updateWorker.showUpdateDialog(false);
+ }
+ }
});
+ updateWorker.checkCurrentVersion(7000);
waitDialog.exec();
- delete reply;
}
-void AboutDialog::serveVersionCheckReply(QNetworkReply *reply)
+void AboutDialog::on_updatesCheckBox_stateChanged(int state)
{
- QString currVersion = "";
- QMessageBox mb;
- mb.setStandardButtons(QMessageBox::Ok);
- if (reply->error()) {
- mb.setIcon(QMessageBox::Critical);
- mb.setWindowTitle(tr("Error!"));
- mb.setText(reply->errorString());
- } else {
- currVersion = QJsonDocument::fromJson(reply->readAll()).object().value("tag_name").toString();
- currVersion.remove('v');
-
- mb.setWindowTitle(tr("Version control"));
- mb.setIcon(QMessageBox::Information);
- if (currVersion == CUTTER_VERSION_FULL) {
- mb.setText(tr("You have latest version and no need to update!"));
- } else {
- mb.setText("" + tr("Current version:") + " " CUTTER_VERSION_FULL "
"
- + "" + tr("Latest version:") + " " + currVersion + "
"
- + tr("For update, please check the link:")
- + ""
- + "https://github.com/radareorg/cutter/releases");
- }
- }
- mb.exec();
+ Config()->setAutoUpdateEnabled(!Config()->getAutoUpdateEnabled());
}
diff --git a/src/dialogs/AboutDialog.h b/src/dialogs/AboutDialog.h
index 669757aa..3d094736 100644
--- a/src/dialogs/AboutDialog.h
+++ b/src/dialogs/AboutDialog.h
@@ -21,8 +21,20 @@ private slots:
void on_buttonBox_rejected();
void on_showVersionButton_clicked();
void on_showPluginsButton_clicked();
+
+ /**
+ * @fn AboutDialog::on_checkForUpdatesButton_clicked()
+ *
+ * @brief Initiates process of checking for updates.
+ */
void on_checkForUpdatesButton_clicked();
- void serveVersionCheckReply(QNetworkReply *reply);
+
+ /**
+ * @fn AboutDialog::on_updatesCheckBox_stateChanged(int state)
+ *
+ * @brief Changes value of autoUpdateEnabled option in settings.
+ */
+ void on_updatesCheckBox_stateChanged(int state);
private:
std::unique_ptr ui;
diff --git a/src/dialogs/AboutDialog.ui b/src/dialogs/AboutDialog.ui
index 96b0695f..dea81d4c 100644
--- a/src/dialogs/AboutDialog.ui
+++ b/src/dialogs/AboutDialog.ui
@@ -76,6 +76,19 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Check for updates on start
+
+
+
diff --git a/src/dialogs/WelcomeDialog.cpp b/src/dialogs/WelcomeDialog.cpp
index a70f47ef..6359467e 100644
--- a/src/dialogs/WelcomeDialog.cpp
+++ b/src/dialogs/WelcomeDialog.cpp
@@ -20,8 +20,9 @@ WelcomeDialog::WelcomeDialog(QWidget *parent) :
ui->logoSvgWidget->load(Config()->getLogoFile());
ui->versionLabel->setText("" + tr("Version ") + CUTTER_VERSION_FULL + "");
ui->themeComboBox->setCurrentIndex(Config()->getTheme());
- ui->themeComboBox->setFixedWidth(200);
- ui->themeComboBox->view()->setFixedWidth(200);
+
+ QSignalBlocker s(ui->updatesCheckBox);
+ ui->updatesCheckBox->setChecked(Config()->getAutoUpdateEnabled());
QStringList langs = Config()->getAvailableTranslations();
ui->languageComboBox->addItems(langs);
@@ -97,3 +98,8 @@ void WelcomeDialog::on_continueButton_clicked()
{
accept();
}
+
+void WelcomeDialog::on_updatesCheckBox_stateChanged(int state)
+{
+ Config()->setAutoUpdateEnabled(!Config()->getAutoUpdateEnabled());
+}
diff --git a/src/dialogs/WelcomeDialog.h b/src/dialogs/WelcomeDialog.h
index 6f8c423a..1ac8627b 100644
--- a/src/dialogs/WelcomeDialog.h
+++ b/src/dialogs/WelcomeDialog.h
@@ -30,6 +30,7 @@ private slots:
void onLanguageComboBox_currentIndexChanged(int index);
void on_checkUpdateButton_clicked();
void on_continueButton_clicked();
+ void on_updatesCheckBox_stateChanged(int state);
private:
Ui::WelcomeDialog *ui;
diff --git a/src/dialogs/WelcomeDialog.ui b/src/dialogs/WelcomeDialog.ui
index a43859d0..4f7c1d38 100644
--- a/src/dialogs/WelcomeDialog.ui
+++ b/src/dialogs/WelcomeDialog.ui
@@ -7,7 +7,7 @@
0
0
806
- 488
+ 620
@@ -122,84 +122,118 @@
-
-
-
- QLayout::SetFixedSize
-
-
- 0
-
-
- 9
-
-
-
-
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
- -
-
-
-
- 0
- 0
-
+
-
+
+
+ 9
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- 0
-
-
-
- 160
- 16
-
+
+ QLayout::SetMaximumSize
-
-
- Native Theme
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ About
+
+
-
-
- Dark Theme
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ 0
+
+
+
+ 16
+ 16
+
+
+
-
+
+ Native Theme
+
+
+ -
+
+ Dark Theme
+
+
+
-
+ -
+
+
+ -
+
+
+ Check for updates on start
+
+
+
+
- -
-
-
-
- 0
- 0
-
+
-
+
+
+ Qt::Horizontal
-
+
- 0
- 0
+ 40
+ 20
-
-
- 16777215
- 16777215
-
-
-
- About
-
-
+