mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 01:43:27 +02:00
Merge pull request #5082 from murillodigital/auto-updater
Checkpoint towards auto updater
This commit is contained in:
commit
b0b52ddcd2
12 changed files with 457 additions and 257 deletions
|
@ -140,7 +140,7 @@ target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES})
|
||||||
# link required hifi libraries
|
# link required hifi libraries
|
||||||
link_hifi_libraries(shared octree environment gpu model render fbx networking entities avatars
|
link_hifi_libraries(shared octree environment gpu model render fbx networking entities avatars
|
||||||
audio audio-client animation script-engine physics
|
audio audio-client animation script-engine physics
|
||||||
render-utils entities-renderer ui)
|
render-utils entities-renderer ui auto-updater)
|
||||||
|
|
||||||
add_dependency_external_projects(sdl2)
|
add_dependency_external_projects(sdl2)
|
||||||
|
|
||||||
|
|
172
interface/resources/qml/UpdateDialog.qml
Normal file
172
interface/resources/qml/UpdateDialog.qml
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
import Hifi 1.0
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
import "controls"
|
||||||
|
import "styles"
|
||||||
|
|
||||||
|
DialogContainer {
|
||||||
|
HifiConstants { id: hifi }
|
||||||
|
id: root
|
||||||
|
objectName: "UpdateDialog"
|
||||||
|
implicitWidth: updateDialog.width
|
||||||
|
implicitHeight: updateDialog.height
|
||||||
|
x: parent ? parent.width / 2 - width / 2 : 0
|
||||||
|
y: parent ? parent.height / 2 - height / 2 : 0
|
||||||
|
|
||||||
|
UpdateDialog {
|
||||||
|
id: updateDialog
|
||||||
|
|
||||||
|
implicitWidth: backgroundRectangle.width
|
||||||
|
implicitHeight: backgroundRectangle.height
|
||||||
|
|
||||||
|
readonly property int inputWidth: 500
|
||||||
|
readonly property int inputHeight: 60
|
||||||
|
readonly property int borderWidth: 30
|
||||||
|
readonly property int closeMargin: 16
|
||||||
|
readonly property int inputSpacing: 16
|
||||||
|
readonly property int buttonWidth: 150
|
||||||
|
readonly property int buttonHeight: 50
|
||||||
|
readonly property int buttonRadius: 15
|
||||||
|
|
||||||
|
signal triggerBuildDownload
|
||||||
|
signal closeUpdateDialog
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: mainContent
|
||||||
|
width: updateDialog.inputWidth
|
||||||
|
spacing: updateDialog.inputSpacing
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: backgroundRectangle
|
||||||
|
color: "#2c86b1"
|
||||||
|
opacity: 0.85
|
||||||
|
radius: updateDialog.closeMargin * 2
|
||||||
|
|
||||||
|
width: updateDialog.inputWidth + updateDialog.borderWidth * 2
|
||||||
|
height: updateDialog.inputHeight * 6 + updateDialog.closeMargin * 2
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: dialogTitle
|
||||||
|
width: updateDialog.inputWidth
|
||||||
|
height: updateDialog.inputHeight
|
||||||
|
radius: height / 2
|
||||||
|
color: "#ebebeb"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
topMargin: updateDialog.inputSpacing
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: updateAvailableText
|
||||||
|
text: "Update Available"
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: updateDialog.inputSpacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: updateDialog.updateAvailableDetails
|
||||||
|
font.pixelSize: 14
|
||||||
|
color: hifi.colors.text
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: updateAvailableText.right
|
||||||
|
leftMargin: 13
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: scrollArea
|
||||||
|
anchors {
|
||||||
|
top: dialogTitle.bottom
|
||||||
|
}
|
||||||
|
contentWidth: updateDialog.inputWidth
|
||||||
|
contentHeight: backgroundRectangle.height - (dialogTitle.height * 2.5)
|
||||||
|
width: updateDialog.inputWidth
|
||||||
|
height: backgroundRectangle.height - (dialogTitle.height * 2.5)
|
||||||
|
flickableDirection: Flickable.VerticalFlick
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
id: releaseNotes
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
width: parent.width
|
||||||
|
readOnly: true
|
||||||
|
text: updateDialog.releaseNotes
|
||||||
|
font.pixelSize: 14
|
||||||
|
color: hifi.colors.text
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: updateDialog.borderWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: downloadButton
|
||||||
|
width: updateDialog.buttonWidth
|
||||||
|
height: updateDialog.buttonHeight
|
||||||
|
radius: updateDialog.buttonRadius
|
||||||
|
color: "green"
|
||||||
|
anchors {
|
||||||
|
top: scrollArea.bottom
|
||||||
|
topMargin: 10
|
||||||
|
right: backgroundRectangle.right
|
||||||
|
rightMargin: 15
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "Upgrade"
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: downloadButtonAction
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: updateDialog.triggerUpgrade()
|
||||||
|
cursorShape: "PointingHandCursor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: cancelButton
|
||||||
|
width: updateDialog.buttonWidth
|
||||||
|
height: updateDialog.buttonHeight
|
||||||
|
radius: updateDialog.buttonRadius
|
||||||
|
color: "red"
|
||||||
|
anchors {
|
||||||
|
top: scrollArea.bottom
|
||||||
|
topMargin: 10
|
||||||
|
right: downloadButton.left
|
||||||
|
rightMargin: 15
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Cancel"
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: cancelButtonAction
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: updateDialog.closeDialog()
|
||||||
|
cursorShape: "PointingHandCursor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,6 +60,7 @@
|
||||||
#include <CursorManager.h>
|
#include <CursorManager.h>
|
||||||
#include <AmbientOcclusionEffect.h>
|
#include <AmbientOcclusionEffect.h>
|
||||||
#include <AudioInjector.h>
|
#include <AudioInjector.h>
|
||||||
|
#include <AutoUpdater.h>
|
||||||
#include <DeferredLightingEffect.h>
|
#include <DeferredLightingEffect.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <EntityScriptingInterface.h>
|
#include <EntityScriptingInterface.h>
|
||||||
|
@ -147,6 +148,7 @@
|
||||||
#include "ui/StandAloneJSConsole.h"
|
#include "ui/StandAloneJSConsole.h"
|
||||||
#include "ui/Stats.h"
|
#include "ui/Stats.h"
|
||||||
#include "ui/AddressBarDialog.h"
|
#include "ui/AddressBarDialog.h"
|
||||||
|
#include "ui/UpdateDialog.h"
|
||||||
|
|
||||||
|
|
||||||
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||||
|
@ -296,6 +298,7 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
auto discoverabilityManager = DependencyManager::set<DiscoverabilityManager>();
|
auto discoverabilityManager = DependencyManager::set<DiscoverabilityManager>();
|
||||||
auto sceneScriptingInterface = DependencyManager::set<SceneScriptingInterface>();
|
auto sceneScriptingInterface = DependencyManager::set<SceneScriptingInterface>();
|
||||||
auto offscreenUi = DependencyManager::set<OffscreenUi>();
|
auto offscreenUi = DependencyManager::set<OffscreenUi>();
|
||||||
|
auto autoUpdater = DependencyManager::set<AutoUpdater>();
|
||||||
auto pathUtils = DependencyManager::set<PathUtils>();
|
auto pathUtils = DependencyManager::set<PathUtils>();
|
||||||
auto actionFactory = DependencyManager::set<InterfaceActionFactory>();
|
auto actionFactory = DependencyManager::set<InterfaceActionFactory>();
|
||||||
|
|
||||||
|
@ -563,8 +566,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
// allow you to move an entity around in your hand
|
// allow you to move an entity around in your hand
|
||||||
_entityEditSender.setPacketsPerSecond(3000); // super high!!
|
_entityEditSender.setPacketsPerSecond(3000); // super high!!
|
||||||
|
|
||||||
checkVersion();
|
|
||||||
|
|
||||||
_overlays.init(); // do this before scripts load
|
_overlays.init(); // do this before scripts load
|
||||||
|
|
||||||
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
||||||
|
@ -636,9 +637,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
ddeTracker->init();
|
ddeTracker->init();
|
||||||
connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled);
|
connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||||
|
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||||
|
applicationUpdater->checkForUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Application::aboutToQuit() {
|
void Application::aboutToQuit() {
|
||||||
emit beforeAboutToQuit();
|
emit beforeAboutToQuit();
|
||||||
|
|
||||||
|
@ -828,6 +832,7 @@ void Application::initializeUi() {
|
||||||
LoginDialog::registerType();
|
LoginDialog::registerType();
|
||||||
MessageDialog::registerType();
|
MessageDialog::registerType();
|
||||||
VrMenu::registerType();
|
VrMenu::registerType();
|
||||||
|
UpdateDialog::registerType();
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
offscreenUi->create(_glWidget->context()->contextHandle());
|
offscreenUi->create(_glWidget->context()->contextHandle());
|
||||||
|
@ -4523,72 +4528,6 @@ void Application::toggleLogDialog() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::checkVersion() {
|
|
||||||
QNetworkRequest latestVersionRequest((QUrl(CHECK_VERSION_URL)));
|
|
||||||
latestVersionRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
|
||||||
latestVersionRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
|
||||||
QNetworkReply* reply = NetworkAccessManager::getInstance().get(latestVersionRequest);
|
|
||||||
connect(reply, SIGNAL(finished()), SLOT(parseVersionXml()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::parseVersionXml() {
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN32
|
|
||||||
QString operatingSystem("win");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
QString operatingSystem("mac");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
QString operatingSystem("ubuntu");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString latestVersion;
|
|
||||||
QUrl downloadUrl;
|
|
||||||
QString releaseNotes("Unavailable");
|
|
||||||
QNetworkReply* sender = qobject_cast<QNetworkReply*>(QObject::sender());
|
|
||||||
|
|
||||||
QXmlStreamReader xml(sender);
|
|
||||||
|
|
||||||
while (!xml.atEnd() && !xml.hasError()) {
|
|
||||||
if (xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == operatingSystem) {
|
|
||||||
while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == operatingSystem)) {
|
|
||||||
if (xml.tokenType() == QXmlStreamReader::StartElement && xml.name().toString() == "version") {
|
|
||||||
xml.readNext();
|
|
||||||
latestVersion = xml.text().toString();
|
|
||||||
}
|
|
||||||
if (xml.tokenType() == QXmlStreamReader::StartElement && xml.name().toString() == "url") {
|
|
||||||
xml.readNext();
|
|
||||||
downloadUrl = QUrl(xml.text().toString());
|
|
||||||
}
|
|
||||||
xml.readNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xml.readNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shouldSkipVersion(latestVersion) && applicationVersion() != latestVersion) {
|
|
||||||
new UpdateDialog(_glWidget, releaseNotes, latestVersion, downloadUrl);
|
|
||||||
}
|
|
||||||
sender->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Application::shouldSkipVersion(QString latestVersion) {
|
|
||||||
QFile skipFile(SKIP_FILENAME);
|
|
||||||
skipFile.open(QIODevice::ReadWrite);
|
|
||||||
QString skipVersion(skipFile.readAll());
|
|
||||||
return (skipVersion == latestVersion || applicationVersion() == "dev");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::skipVersion(QString latestVersion) {
|
|
||||||
QFile skipFile(SKIP_FILENAME);
|
|
||||||
skipFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
|
||||||
skipFile.seek(0);
|
|
||||||
skipFile.write(latestVersion.toStdString().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::takeSnapshot() {
|
void Application::takeSnapshot() {
|
||||||
QMediaPlayer* player = new QMediaPlayer();
|
QMediaPlayer* player = new QMediaPlayer();
|
||||||
QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav");
|
QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav");
|
||||||
|
|
|
@ -66,7 +66,6 @@
|
||||||
#include "ui/SnapshotShareDialog.h"
|
#include "ui/SnapshotShareDialog.h"
|
||||||
#include "ui/LodToolsDialog.h"
|
#include "ui/LodToolsDialog.h"
|
||||||
#include "ui/LogDialog.h"
|
#include "ui/LogDialog.h"
|
||||||
#include "ui/UpdateDialog.h"
|
|
||||||
#include "ui/overlays/Overlays.h"
|
#include "ui/overlays/Overlays.h"
|
||||||
#include "ui/ApplicationOverlay.h"
|
#include "ui/ApplicationOverlay.h"
|
||||||
#include "ui/RunningScriptsWidget.h"
|
#include "ui/RunningScriptsWidget.h"
|
||||||
|
@ -312,8 +311,6 @@ public:
|
||||||
|
|
||||||
NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; }
|
NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; }
|
||||||
|
|
||||||
void skipVersion(QString latestVersion);
|
|
||||||
|
|
||||||
QStringList getRunningScripts() { return _scriptEnginesHash.keys(); }
|
QStringList getRunningScripts() { return _scriptEnginesHash.keys(); }
|
||||||
ScriptEngine* getScriptEngine(QString scriptHash) { return _scriptEnginesHash.contains(scriptHash) ? _scriptEnginesHash[scriptHash] : NULL; }
|
ScriptEngine* getScriptEngine(QString scriptHash) { return _scriptEnginesHash.contains(scriptHash) ? _scriptEnginesHash[scriptHash] : NULL; }
|
||||||
|
|
||||||
|
@ -460,8 +457,6 @@ private slots:
|
||||||
void restoreMirrorView();
|
void restoreMirrorView();
|
||||||
void shrinkMirrorView();
|
void shrinkMirrorView();
|
||||||
|
|
||||||
void parseVersionXml();
|
|
||||||
|
|
||||||
void manageRunningScriptsWidgetVisibility(bool shown);
|
void manageRunningScriptsWidgetVisibility(bool shown);
|
||||||
|
|
||||||
void runTests();
|
void runTests();
|
||||||
|
@ -627,9 +622,6 @@ private:
|
||||||
|
|
||||||
FileLogger* _logger;
|
FileLogger* _logger;
|
||||||
|
|
||||||
void checkVersion();
|
|
||||||
void displayUpdateDialog();
|
|
||||||
bool shouldSkipVersion(QString latestVersion);
|
|
||||||
void takeSnapshot();
|
void takeSnapshot();
|
||||||
|
|
||||||
TouchEvent _lastTouchEvent;
|
TouchEvent _lastTouchEvent;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "OctreeStatsDialog.h"
|
#include "OctreeStatsDialog.h"
|
||||||
#include "PreferencesDialog.h"
|
#include "PreferencesDialog.h"
|
||||||
#include "ScriptEditorWindow.h"
|
#include "ScriptEditorWindow.h"
|
||||||
|
#include "UpdateDialog.h"
|
||||||
|
|
||||||
|
|
||||||
void DialogsManager::toggleAddressBar() {
|
void DialogsManager::toggleAddressBar() {
|
||||||
|
@ -50,6 +51,10 @@ void DialogsManager::showLoginDialog() {
|
||||||
LoginDialog::show();
|
LoginDialog::show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsManager::showUpdateDialog() {
|
||||||
|
UpdateDialog::show();
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsManager::octreeStatsDetails() {
|
void DialogsManager::octreeStatsDetails() {
|
||||||
if (!_octreeStatsDialog) {
|
if (!_octreeStatsDialog) {
|
||||||
_octreeStatsDialog = new OctreeStatsDialog(qApp->getWindow(), qApp->getOcteeSceneStats());
|
_octreeStatsDialog = new OctreeStatsDialog(qApp->getWindow(), qApp->getOcteeSceneStats());
|
||||||
|
|
|
@ -35,6 +35,7 @@ class ScriptEditorWindow;
|
||||||
class QMessageBox;
|
class QMessageBox;
|
||||||
class AvatarAppearanceDialog;
|
class AvatarAppearanceDialog;
|
||||||
class DomainConnectionDialog;
|
class DomainConnectionDialog;
|
||||||
|
class UpdateDialog;
|
||||||
|
|
||||||
class DialogsManager : public QObject, public Dependency {
|
class DialogsManager : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -64,6 +65,9 @@ public slots:
|
||||||
void showIRCLink();
|
void showIRCLink();
|
||||||
void changeAvatarAppearance();
|
void changeAvatarAppearance();
|
||||||
void showDomainConnectionDialog();
|
void showDomainConnectionDialog();
|
||||||
|
|
||||||
|
// Application Update
|
||||||
|
void showUpdateDialog();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void toggleToolWindow();
|
void toggleToolWindow();
|
||||||
|
@ -101,6 +105,7 @@ private:
|
||||||
QPointer<ScriptEditorWindow> _scriptEditor;
|
QPointer<ScriptEditorWindow> _scriptEditor;
|
||||||
QPointer<AvatarAppearanceDialog> _avatarAppearanceDialog;
|
QPointer<AvatarAppearanceDialog> _avatarAppearanceDialog;
|
||||||
QPointer<DomainConnectionDialog> _domainConnectionDialog;
|
QPointer<DomainConnectionDialog> _domainConnectionDialog;
|
||||||
|
QPointer<UpdateDialog> _updateDialog;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DialogsManager_h
|
#endif // hifi_DialogsManager_h
|
||||||
|
|
|
@ -2,54 +2,50 @@
|
||||||
// UpdateDialog.cpp
|
// UpdateDialog.cpp
|
||||||
// interface/src/ui
|
// interface/src/ui
|
||||||
//
|
//
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Created by Leonardo Murillo on 6/3/15.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <QDesktopServices>
|
|
||||||
|
|
||||||
#include "ui_updateDialog.h"
|
|
||||||
|
|
||||||
#include "Application.h"
|
|
||||||
#include "UpdateDialog.h"
|
#include "UpdateDialog.h"
|
||||||
|
|
||||||
|
#include <AutoUpdater.h>
|
||||||
|
|
||||||
UpdateDialog::UpdateDialog(QWidget *parent, const QString& releaseNotes, const QString& latestVersion, const QUrl& downloadURL) :
|
#include "DependencyManager.h"
|
||||||
QDialog(parent),
|
|
||||||
_latestVersion(latestVersion),
|
HIFI_QML_DEF(UpdateDialog)
|
||||||
_downloadUrl(downloadURL)
|
|
||||||
|
UpdateDialog::UpdateDialog(QQuickItem* parent) :
|
||||||
|
OffscreenQmlDialog(parent)
|
||||||
{
|
{
|
||||||
Ui::Dialog dialogUI;
|
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||||
dialogUI.setupUi(this);
|
int currentVersion = QCoreApplication::applicationVersion().toInt();
|
||||||
|
int latestVersion = applicationUpdater.data()->getBuildData().lastKey();
|
||||||
QString updateRequired = QString("You are currently running build %1, the latest build released is %2."
|
int versionsBehind = latestVersion - currentVersion;
|
||||||
"\n\nPlease download and install the most recent release to access the latest features and bug fixes.")
|
_updateAvailableDetails = "v" + QString::number(latestVersion) + " released on " + applicationUpdater.data()->getBuildData()[latestVersion]["releaseTime"];
|
||||||
.arg(Application::getInstance()->applicationVersion(), latestVersion);
|
_updateAvailableDetails += "\nYou are " + QString::number(versionsBehind) + " versions behind";
|
||||||
|
_releaseNotes = applicationUpdater.data()->getBuildData()[latestVersion]["releaseNotes"];
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
QPushButton* downloadButton = findChild<QPushButton*>("downloadButton");
|
|
||||||
QPushButton* skipButton = findChild<QPushButton*>("skipButton");
|
|
||||||
QPushButton* closeButton = findChild<QPushButton*>("closeButton");
|
|
||||||
QLabel* updateContent = findChild<QLabel*>("updateContent");
|
|
||||||
|
|
||||||
updateContent->setText(updateRequired);
|
|
||||||
|
|
||||||
connect(downloadButton, SIGNAL(released()), this, SLOT(handleDownload()));
|
|
||||||
connect(skipButton, SIGNAL(released()), this, SLOT(handleSkip()));
|
|
||||||
connect(closeButton, SIGNAL(released()), this, SLOT(close()));
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(this, "show", Qt::QueuedConnection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDialog::handleDownload() {
|
const QString& UpdateDialog::updateAvailableDetails() const {
|
||||||
QDesktopServices::openUrl(_downloadUrl);
|
return _updateAvailableDetails;
|
||||||
Application::getInstance()->quit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDialog::handleSkip() {
|
const QString& UpdateDialog::releaseNotes() const {
|
||||||
Application::getInstance()->skipVersion(_latestVersion);
|
return _releaseNotes;
|
||||||
this->close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateDialog::closeDialog() {
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialog::hide() {
|
||||||
|
((QQuickItem*)parent())->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialog::triggerUpgrade() {
|
||||||
|
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||||
|
applicationUpdater.data()->performAutoUpdate(applicationUpdater.data()->getBuildData().lastKey());
|
||||||
|
}
|
|
@ -2,30 +2,42 @@
|
||||||
// UpdateDialog.h
|
// UpdateDialog.h
|
||||||
// interface/src/ui
|
// interface/src/ui
|
||||||
//
|
//
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Created by Leonardo Murillo on 6/3/15.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef hifi_UpdateDialog_h
|
#ifndef hifi_UpdateDialog_h
|
||||||
#define hifi_UpdateDialog_h
|
#define hifi_UpdateDialog_h
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QtCore/QCoreApplication>
|
||||||
|
|
||||||
class UpdateDialog : public QDialog {
|
#include <OffscreenQmlDialog.h>
|
||||||
|
|
||||||
|
class UpdateDialog : public OffscreenQmlDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
HIFI_QML_DECL
|
||||||
|
|
||||||
|
Q_PROPERTY(QString updateAvailableDetails READ updateAvailableDetails)
|
||||||
|
Q_PROPERTY(QString releaseNotes READ releaseNotes)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateDialog(QWidget* parent, const QString& releaseNotes, const QString& latestVersion, const QUrl& downloadURL);
|
UpdateDialog(QQuickItem* parent = nullptr);
|
||||||
|
const QString& updateAvailableDetails() const;
|
||||||
|
const QString& releaseNotes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _latestVersion;
|
QString _updateAvailableDetails;
|
||||||
QUrl _downloadUrl;
|
QString _releaseNotes;
|
||||||
|
|
||||||
private slots:
|
protected:
|
||||||
void handleDownload();
|
void hide();
|
||||||
void handleSkip();
|
Q_INVOKABLE void triggerUpgrade();
|
||||||
|
Q_INVOKABLE void closeDialog();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_UpdateDialog_h
|
#endif // hifi_UpdateDialog_h
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>Dialog</class>
|
|
||||||
<widget class="QDialog" name="Dialog">
|
|
||||||
<property name="windowModality">
|
|
||||||
<enum>Qt::NonModal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>750</width>
|
|
||||||
<height>213</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="cursor">
|
|
||||||
<cursorShape>PointingHandCursor</cursorShape>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Update Required</string>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QLabel" name="updateContent">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>50</x>
|
|
||||||
<y>20</y>
|
|
||||||
<width>641</width>
|
|
||||||
<height>111</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Arial</family>
|
|
||||||
<pointsize>-1</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">font-family: Arial;
|
|
||||||
font-size: 20px;</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="layoutWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>360</x>
|
|
||||||
<y>160</y>
|
|
||||||
<width>374</width>
|
|
||||||
<height>42</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="downloadButton">
|
|
||||||
<property name="cursor">
|
|
||||||
<cursorShape>PointingHandCursor</cursorShape>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true"> background-color: #333333;
|
|
||||||
border-width: 0;
|
|
||||||
border-radius: 9px;
|
|
||||||
border-radius: 9px;
|
|
||||||
font-family: Arial;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 100;
|
|
||||||
color: #b7b7b7;
|
|
||||||
width: 120px;
|
|
||||||
height: 40px;</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Download</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="skipButton">
|
|
||||||
<property name="cursor">
|
|
||||||
<cursorShape>PointingHandCursor</cursorShape>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true"> background-color: #333333;
|
|
||||||
border-width: 0;
|
|
||||||
border-radius: 9px;
|
|
||||||
border-radius: 9px;
|
|
||||||
font-family: Arial;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 100;
|
|
||||||
color: #b7b7b7;
|
|
||||||
width: 120px;
|
|
||||||
height: 40px;</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Skip Version</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="closeButton">
|
|
||||||
<property name="cursor">
|
|
||||||
<cursorShape>PointingHandCursor</cursorShape>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true"> background-color: #333333;
|
|
||||||
border-width: 0;
|
|
||||||
border-radius: 9px;
|
|
||||||
border-radius: 9px;
|
|
||||||
font-family: Arial;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 100;
|
|
||||||
color: #b7b7b7;
|
|
||||||
width: 120px;
|
|
||||||
height: 40px;</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Close</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
3
libraries/auto-updater/CMakeLists.txt
Normal file
3
libraries/auto-updater/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
set(TARGET_NAME auto-updater)
|
||||||
|
setup_hifi_library(Network)
|
||||||
|
link_hifi_libraries(shared networking)
|
140
libraries/auto-updater/src/AutoUpdater.cpp
Normal file
140
libraries/auto-updater/src/AutoUpdater.cpp
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
//
|
||||||
|
// AutoUpdater.cpp
|
||||||
|
// libraries/auto-update/src
|
||||||
|
//
|
||||||
|
// Created by Leonardo Murillo on 6/1/2015.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AutoUpdater.h"
|
||||||
|
|
||||||
|
#include <NetworkAccessManager.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
AutoUpdater::AutoUpdater() {
|
||||||
|
#if defined Q_OS_WIN32
|
||||||
|
_operatingSystem = "windows";
|
||||||
|
#elif defined Q_OS_MAC
|
||||||
|
_operatingSystem = "mac";
|
||||||
|
#elif defined Q_OS_LINUX
|
||||||
|
_operatingSystem = "ubuntu";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
connect(this, SIGNAL(latestVersionDataParsed()), this, SLOT(checkVersionAndNotify()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::checkForUpdate() {
|
||||||
|
this->getLatestVersionData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::getLatestVersionData() {
|
||||||
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
QNetworkRequest latestVersionRequest(BUILDS_XML_URL);
|
||||||
|
latestVersionRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||||
|
QNetworkReply* reply = networkAccessManager.get(latestVersionRequest);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &AutoUpdater::parseLatestVersionData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::parseLatestVersionData() {
|
||||||
|
QNetworkReply* sender = qobject_cast<QNetworkReply*>(QObject::sender());
|
||||||
|
|
||||||
|
QXmlStreamReader xml(sender);
|
||||||
|
|
||||||
|
int version;
|
||||||
|
QString downloadUrl;
|
||||||
|
QString releaseTime;
|
||||||
|
QString releaseNotes;
|
||||||
|
QString commitSha;
|
||||||
|
QString pullRequestNumber;
|
||||||
|
|
||||||
|
while (!xml.atEnd() && !xml.hasError()) {
|
||||||
|
if (xml.name().toString() == "project" &&
|
||||||
|
xml.attributes().hasAttribute("name") &&
|
||||||
|
xml.attributes().value("name").toString() == "interface") {
|
||||||
|
xml.readNext();
|
||||||
|
|
||||||
|
while (!xml.atEnd() && !xml.hasError() && xml.name().toString() != "project") {
|
||||||
|
if (xml.name().toString() == "platform" &&
|
||||||
|
xml.attributes().hasAttribute("name") &&
|
||||||
|
xml.attributes().value("name").toString() == _operatingSystem) {
|
||||||
|
xml.readNext();
|
||||||
|
while (!xml.atEnd() && !xml.hasError() &&
|
||||||
|
xml.name().toString() != "platform") {
|
||||||
|
|
||||||
|
if (xml.name().toString() == "build" && xml.tokenType() != QXmlStreamReader::EndElement) {
|
||||||
|
xml.readNext();
|
||||||
|
version = xml.readElementText().toInt();
|
||||||
|
xml.readNext();
|
||||||
|
downloadUrl = xml.readElementText();
|
||||||
|
xml.readNext();
|
||||||
|
releaseTime = xml.readElementText();
|
||||||
|
xml.readNext();
|
||||||
|
if (xml.name().toString() == "notes" && xml.tokenType() != QXmlStreamReader::EndElement) {
|
||||||
|
xml.readNext();
|
||||||
|
while (!xml.atEnd() && !xml.hasError() && xml.name().toString() != "notes") {
|
||||||
|
if (xml.name().toString() == "note" && xml.tokenType() != QXmlStreamReader::EndElement) {
|
||||||
|
releaseNotes = releaseNotes + "\n" + xml.readElementText();
|
||||||
|
}
|
||||||
|
xml.readNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xml.readNext();
|
||||||
|
commitSha = xml.readElementText();
|
||||||
|
xml.readNext();
|
||||||
|
pullRequestNumber = xml.readElementText();
|
||||||
|
appendBuildData(version, downloadUrl, releaseTime, releaseNotes, pullRequestNumber);
|
||||||
|
releaseNotes = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.readNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xml.readNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
xml.readNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sender->deleteLater();
|
||||||
|
emit latestVersionDataParsed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::checkVersionAndNotify() {
|
||||||
|
int latestVersionAvailable = _builds.lastKey();
|
||||||
|
if (QCoreApplication::applicationVersion() != "dev" &&
|
||||||
|
QCoreApplication::applicationVersion().toInt() < latestVersionAvailable) {
|
||||||
|
emit newVersionIsAvailable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::performAutoUpdate(int version) {
|
||||||
|
// NOTE: This is not yet auto updating - however this is a checkpoint towards that end
|
||||||
|
// Next PR will handle the automatic download, upgrading and application restart
|
||||||
|
const QMap<QString, QString>& chosenVersion = _builds.value(version);
|
||||||
|
const QUrl& downloadUrl = chosenVersion.value("downloadUrl");
|
||||||
|
QDesktopServices::openUrl(downloadUrl);
|
||||||
|
QCoreApplication::quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::downloadUpdateVersion(int version) {
|
||||||
|
emit newVersionIsDownloaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::appendBuildData(int versionNumber,
|
||||||
|
const QString& downloadURL,
|
||||||
|
const QString& releaseTime,
|
||||||
|
const QString& releaseNotes,
|
||||||
|
const QString& pullRequestNumber) {
|
||||||
|
|
||||||
|
QMap<QString, QString> thisBuildDetails;
|
||||||
|
thisBuildDetails.insert("downloadUrl", downloadURL);
|
||||||
|
thisBuildDetails.insert("releaseTime", releaseTime);
|
||||||
|
thisBuildDetails.insert("releaseNotes", releaseNotes);
|
||||||
|
thisBuildDetails.insert("pullRequestNumber", pullRequestNumber);
|
||||||
|
_builds.insert(versionNumber, thisBuildDetails);
|
||||||
|
|
||||||
|
}
|
68
libraries/auto-updater/src/AutoUpdater.h
Normal file
68
libraries/auto-updater/src/AutoUpdater.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
//
|
||||||
|
// AutoUpdater.h
|
||||||
|
// libraries/auto-update/src
|
||||||
|
//
|
||||||
|
// Created by Leonardo Murillo on 6/1/2015.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_AutoUpdater_h
|
||||||
|
#define hifi_AutoUpdater_h
|
||||||
|
|
||||||
|
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtCore/QXmlStreamAttributes>
|
||||||
|
#include <QtCore/QXmlStreamReader>
|
||||||
|
#include <QtGui/QDesktopServices>
|
||||||
|
#include <QtNetwork/QNetworkAccessManager>
|
||||||
|
#include <QtNetwork/QNetworkConfiguration>
|
||||||
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
#include <QtNetwork/QNetworkRequest>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
const QUrl BUILDS_XML_URL("https://highfidelity.com/builds.xml");
|
||||||
|
|
||||||
|
class AutoUpdater : public QObject, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoUpdater();
|
||||||
|
|
||||||
|
void checkForUpdate();
|
||||||
|
const QMap<int, QMap<QString, QString>>& getBuildData() { return _builds; }
|
||||||
|
void performAutoUpdate(int version);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void latestVersionDataParsed();
|
||||||
|
void newVersionIsAvailable();
|
||||||
|
void newVersionIsDownloaded();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMap<int, QMap<QString, QString>> _builds;
|
||||||
|
QString _operatingSystem;
|
||||||
|
|
||||||
|
void getLatestVersionData();
|
||||||
|
void downloadUpdateVersion(int version);
|
||||||
|
void appendBuildData(int versionNumber,
|
||||||
|
const QString& downloadURL,
|
||||||
|
const QString& releaseTime,
|
||||||
|
const QString& releaseNotes,
|
||||||
|
const QString& pullRequestNumber);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void parseLatestVersionData();
|
||||||
|
void checkVersionAndNotify();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _hifi_AutoUpdater_h
|
Loading…
Reference in a new issue