From be0b2c22699e78ac60276fb3ab6477c033208f20 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 26 Sep 2018 09:01:42 -0700 Subject: [PATCH] Stable desktop version check --- ChangeLog.md | 3 +- src/QGCApplication.cc | 89 +++++++++++++++++++++++++++++++++++++++++++------ src/QGCApplication.h | 9 +++++ src/api/QGCCorePlugin.h | 11 ++++++ 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 3a8032e..f4f2098 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,7 +4,8 @@ Note: This file only contains high level features or important fixes. ## 3.4 -### 3.4.4 - Not yet released +### 3.4.4 +* Stable desktop versions now inform user at boot if newer version is available. * Multi-Vehicle Start Mission and Pause now work correctly. Issue #6864. ### 3.4.3 diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 1f8f215..12d22ef 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef QGC_ENABLE_BLUETOOTH #include @@ -86,6 +87,7 @@ #include "EditPositionDialogController.h" #include "FactValueSliderListModel.h" #include "KMLFileHelper.h" +#include "QGCFileDownload.h" #ifndef NO_SERIAL_LINK #include "SerialLink.h" @@ -148,20 +150,24 @@ static QObject* kmlFileHelperSingletonFactory(QQmlEngine*, QJSEngine*) QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) #ifdef __mobile__ - : QGuiApplication (argc, argv) - , _qmlAppEngine (NULL) + : QGuiApplication (argc, argv) + , _qmlAppEngine (nullptr) #else - : QApplication (argc, argv) + : QApplication (argc, argv) #endif - , _runningUnitTests (unitTesting) - , _logOutput (false) - , _fakeMobile (false) - , _settingsUpgraded (false) + , _runningUnitTests (unitTesting) + , _logOutput (false) + , _fakeMobile (false) + , _settingsUpgraded (false) + , _majorVersion (0) + , _minorVersion (0) + , _buildVersion (0) + , _currentVersionDownload (nullptr) #ifdef QT_DEBUG - , _testHighDPI (false) + , _testHighDPI (false) #endif - , _toolbox (NULL) - , _bluetoothAvailable (false) + , _toolbox (nullptr) + , _bluetoothAvailable (false) { _app = this; @@ -322,6 +328,8 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) _toolbox = new QGCToolbox(this); _toolbox->setChildToolboxes(); + + _checkForNewVersion(); } void QGCApplication::_shutdown(void) @@ -692,3 +700,64 @@ bool QGCApplication::isInternetAvailable() { return getQGCMapEngine()->isInternetActive(); } + +void QGCApplication::_checkForNewVersion(void) +{ +#ifndef __mobile__ + if (!_runningUnitTests) { + if (_parseVersionText(applicationVersion(), _majorVersion, _minorVersion, _buildVersion)) { + QString versionCheckFile = toolbox()->corePlugin()->stableVersionCheckFileUrl(); + if (!versionCheckFile.isEmpty()) { + _currentVersionDownload = new QGCFileDownload(this); + connect(_currentVersionDownload, &QGCFileDownload::downloadFinished, this, &QGCApplication::_currentVersionDownloadFinished); + connect(_currentVersionDownload, &QGCFileDownload::error, this, &QGCApplication::_currentVersionDownloadError); + _currentVersionDownload->download(versionCheckFile); + } + } + } +#endif +} + +void QGCApplication::_currentVersionDownloadFinished(QString remoteFile, QString localFile) +{ + Q_UNUSED(remoteFile); + + QFile versionFile(localFile); + if (versionFile.open(QIODevice::ReadOnly)) { + QTextStream textStream(&versionFile); + QString version = textStream.readLine(); + + qDebug() << version; + + int majorVersion, minorVersion, buildVersion; + if (_parseVersionText(version, majorVersion, minorVersion, buildVersion)) { + if (_majorVersion < majorVersion || + (_majorVersion == majorVersion && _minorVersion < minorVersion) || + (_majorVersion == majorVersion && _minorVersion == minorVersion && _buildVersion < buildVersion)) { + QGCMessageBox::information(tr("New Version Available"), tr("There is a newer version of %1 available. You can download it from %2.").arg(applicationName()).arg(toolbox()->corePlugin()->stableDownloadLocation())); + } + } + } + + _currentVersionDownload->deleteLater(); +} + +void QGCApplication::_currentVersionDownloadError(QString errorMsg) +{ + Q_UNUSED(errorMsg); + _currentVersionDownload->deleteLater(); +} + +bool QGCApplication::_parseVersionText(const QString& versionString, int& majorVersion, int& minorVersion, int& buildVersion) +{ + QRegularExpression regExp("v(\\d+)\\.(\\d+)\\.(\\d+)"); + QRegularExpressionMatch match = regExp.match(versionString); + if (match.hasMatch() && match.lastCapturedIndex() == 3) { + majorVersion = match.captured(1).toInt(); + minorVersion = match.captured(2).toInt(); + buildVersion = match.captured(3).toInt(); + return true; + } + + return false; +} diff --git a/src/QGCApplication.h b/src/QGCApplication.h index 0c098f1..ad2c3a6 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -42,6 +42,7 @@ class QGCSingleton; class MainWindow; class QGCToolbox; +class QGCFileDownload; /** * @brief The main application and management class. @@ -152,9 +153,13 @@ public: private slots: void _missingParamsDisplay(void); + void _currentVersionDownloadFinished(QString remoteFile, QString localFile); + void _currentVersionDownloadError(QString errorMsg); + bool _parseVersionText(const QString& versionString, int& majorVersion, int& minorVersion, int& buildVersion); private: QObject* _rootQmlObject(void); + void _checkForNewVersion(void); #ifdef __mobile__ QQmlApplicationEngine* _qmlAppEngine; @@ -170,6 +175,10 @@ private: QStringList _missingParams; ///< List of missing facts to be displayed bool _fakeMobile; ///< true: Fake ui into displaying mobile interface bool _settingsUpgraded; ///< true: Settings format has been upgrade to new version + int _majorVersion; + int _minorVersion; + int _buildVersion; + QGCFileDownload* _currentVersionDownload; #ifdef QT_DEBUG bool _testHighDPI; ///< true: double fonts sizes for simulating high dpi devices diff --git a/src/api/QGCCorePlugin.h b/src/api/QGCCorePlugin.h index 24ac418..da1e5f3 100644 --- a/src/api/QGCCorePlugin.h +++ b/src/api/QGCCorePlugin.h @@ -112,6 +112,17 @@ public: /// should derive from QmlComponentInfo and set the url property. virtual QmlObjectListModel* customMapItems(void); + /// Returns the url to download the stable version check file. Return QString() to indicate no version check should be performed. + /// Default implemenentation returns QGC Stable file location. Custom builds must override to turn off or provide their own location. + /// The contents of this file should be a single line in the form: + /// v3.4.4 + /// This indicates the latest stable version number. + virtual QString stableVersionCheckFileUrl(void) { return QString("https://s3-us-west-2.amazonaws.com/qgroundcontrol/latest/QGC.version.txt"); } + + /// Returns the user visible url to show user where to download new stable builds from. + /// Custom builds must override to provide their own location. + virtual QString stableDownloadLocation(void) { return QString("qgroundcontrol.com"); } + bool showTouchAreas(void) const { return _showTouchAreas; } bool showAdvancedUI(void) const { return _showAdvancedUI; } void setShowTouchAreas(bool show);