First implementation of Update Notification.
--HG-- branch : feature
This commit is contained in:
parent
e4d6df06b7
commit
a94daf6834
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "mainwindow.h"
|
||||
#include "core/vapplication.h"
|
||||
#include "../fervor/fvupdater.h"
|
||||
|
||||
#include <QMessageBox> // For QT_REQUIRE_VERSION
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -55,6 +57,12 @@ int main(int argc, char *argv[])
|
|||
|
||||
app.InitOptions();
|
||||
|
||||
// Set feed URL before doing anything else
|
||||
FvUpdater::sharedUpdater()->SetFeedURL("http://localhost/updateapp/Appcast.xml");
|
||||
|
||||
// Check for updates automatically
|
||||
FvUpdater::sharedUpdater()->CheckForUpdatesSilent();
|
||||
|
||||
MainWindow w;
|
||||
#if !defined(Q_OS_MAC)
|
||||
app.setWindowIcon(QIcon(":/icon/64x64/icon64x64.png"));
|
||||
|
|
|
@ -536,6 +536,15 @@ DEPENDPATH += $$PWD/../../libs/vgeometry
|
|||
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vgeometry/$${DESTDIR}/vgeometry.lib
|
||||
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vgeometry/$${DESTDIR}/libvgeometry.a
|
||||
|
||||
# Fervor static library (depend on VMisc, IFC)
|
||||
unix|win32: LIBS += -L$$OUT_PWD/../../libs/fervor/$${DESTDIR}/ -lfervor
|
||||
|
||||
INCLUDEPATH += $$PWD/../../libs/fervor
|
||||
DEPENDPATH += $$PWD/../../libs/fervor
|
||||
|
||||
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/fervor/$${DESTDIR}/fervor.lib
|
||||
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/fervor/$${DESTDIR}/libfervor.a
|
||||
|
||||
# IFC static library (depend on QMuParser, VMisc)
|
||||
unix|win32: LIBS += -L$$OUT_PWD/../../libs/ifc/$${DESTDIR}/ -lifc
|
||||
|
||||
|
|
7
src/libs/fervor/LICENSE
Normal file
7
src/libs/fervor/LICENSE
Normal file
|
@ -0,0 +1,7 @@
|
|||
Copyright (c) 2012 Linas Valiukas and others.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
15
src/libs/fervor/fervor.pri
Normal file
15
src/libs/fervor/fervor.pri
Normal file
|
@ -0,0 +1,15 @@
|
|||
# ADD TO EACH PATH $$PWD VARIABLE!!!!!!
|
||||
# This need for corect working file translations.pro
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/fvupdatewindow.cpp \
|
||||
$$PWD/fvupdater.cpp \
|
||||
$$PWD/fvavailableupdate.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/fvupdatewindow.h \
|
||||
$$PWD/fvupdater.h \
|
||||
$$PWD/fvavailableupdate.h
|
||||
|
||||
FORMS += \
|
||||
$$PWD/fvupdatewindow.ui
|
107
src/libs/fervor/fervor.pro
Normal file
107
src/libs/fervor/fervor.pro
Normal file
|
@ -0,0 +1,107 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2016-07-14T11:55:03
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
# File with common stuff for whole project
|
||||
include(../../../common.pri)
|
||||
|
||||
QT += network widgets
|
||||
|
||||
# Name of library
|
||||
TARGET = fervor
|
||||
|
||||
# We want to create a library
|
||||
TEMPLATE = lib
|
||||
|
||||
CONFIG += \
|
||||
staticlib \# Making static library
|
||||
c++11 # We use C++11 standard
|
||||
|
||||
# Use out-of-source builds (shadow builds)
|
||||
CONFIG -= debug_and_release debug_and_release_target
|
||||
|
||||
# Since Qt 5.4.0 the source code location is recorded only in debug builds.
|
||||
# We need this information also in release builds. For this need define QT_MESSAGELOGCONTEXT.
|
||||
DEFINES += QT_MESSAGELOGCONTEXT
|
||||
|
||||
include(fervor.pri)
|
||||
|
||||
# This is static library so no need in "make install"
|
||||
|
||||
# directory for executable file
|
||||
DESTDIR = bin
|
||||
|
||||
# files created moc
|
||||
MOC_DIR = moc
|
||||
|
||||
# objecs files
|
||||
OBJECTS_DIR = obj
|
||||
|
||||
# Directory for files created uic
|
||||
UI_DIR = uic
|
||||
|
||||
# Set using ccache. Function enable_ccache() defined in common.pri.
|
||||
$$enable_ccache()
|
||||
|
||||
CONFIG(debug, debug|release){
|
||||
# Debug mode
|
||||
unix {
|
||||
#Turn on compilers warnings.
|
||||
*-g++{
|
||||
QMAKE_CXXFLAGS += \
|
||||
# Key -isystem disable checking errors in system headers.
|
||||
-isystem "$${OUT_PWD}/$${MOC_DIR}" \
|
||||
-isystem "$${OUT_PWD}/$${UI_DIR}" \
|
||||
$$GCC_DEBUG_CXXFLAGS # See common.pri for more details.
|
||||
|
||||
noAddressSanitizer{ # For enable run qmake with CONFIG+=noAddressSanitizer
|
||||
# do nothing
|
||||
} else {
|
||||
#gcc’s 4.8.0 Address Sanitizer
|
||||
#http://blog.qt.digia.com/blog/2013/04/17/using-gccs-4-8-0-address-sanitizer-with-qt/
|
||||
QMAKE_CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||
QMAKE_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||
QMAKE_LFLAGS += -fsanitize=address
|
||||
}
|
||||
}
|
||||
clang*{
|
||||
QMAKE_CXXFLAGS += \
|
||||
# Key -isystem disable checking errors in system headers.
|
||||
-isystem "$${OUT_PWD}/$${MOC_DIR}" \
|
||||
-isystem "$${OUT_PWD}/$${UI_DIR}" \
|
||||
$$CLANG_DEBUG_CXXFLAGS # See common.pri for more details.
|
||||
}
|
||||
*-icc-*{
|
||||
QMAKE_CXXFLAGS += \
|
||||
-isystem "$${OUT_PWD}/$${MOC_DIR}" \
|
||||
-isystem "$${OUT_PWD}/$${UI_DIR}" \
|
||||
$$ICC_DEBUG_CXXFLAGS
|
||||
}
|
||||
} else {
|
||||
*-g++{
|
||||
QMAKE_CXXFLAGS += $$GCC_DEBUG_CXXFLAGS # See common.pri for more details.
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
# Release mode
|
||||
!win32-msvc*:CONFIG += silent
|
||||
DEFINES += V_NO_ASSERT
|
||||
!unix:*-g++{
|
||||
QMAKE_CXXFLAGS += -fno-omit-frame-pointer # Need for exchndl.dll
|
||||
}
|
||||
|
||||
noDebugSymbols{ # For enable run qmake with CONFIG+=noDebugSymbols
|
||||
# do nothing
|
||||
} else {
|
||||
!macx:!win32-msvc*{
|
||||
# Turn on debug symbols in release mode on Unix systems.
|
||||
# On Mac OS X temporarily disabled. TODO: find way how to strip binary file.
|
||||
QMAKE_CXXFLAGS_RELEASE += -g -gdwarf-3
|
||||
QMAKE_CFLAGS_RELEASE += -g -gdwarf-3
|
||||
QMAKE_LFLAGS_RELEASE =
|
||||
}
|
||||
}
|
||||
}
|
74
src/libs/fervor/fvavailableupdate.cpp
Normal file
74
src/libs/fervor/fvavailableupdate.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************************************
|
||||
**
|
||||
** Copyright (c) 2012 Linas Valiukas and others.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
** software and associated documentation files (the "Software"), to deal in the Software
|
||||
** without restriction, including without limitation the rights to use, copy, modify,
|
||||
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included in all copies or
|
||||
** substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
******************************************************************************************************/
|
||||
|
||||
#include "fvavailableupdate.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
FvAvailableUpdate::FvAvailableUpdate(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_enclosureUrl(),
|
||||
m_enclosureVersion(),
|
||||
m_enclosurePlatform()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QUrl FvAvailableUpdate::GetEnclosureUrl() const
|
||||
{
|
||||
return m_enclosureUrl;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvAvailableUpdate::SetEnclosureUrl(const QUrl &enclosureUrl)
|
||||
{
|
||||
m_enclosureUrl = enclosureUrl;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvAvailableUpdate::SetEnclosureUrl(const QString &enclosureUrl)
|
||||
{
|
||||
SetEnclosureUrl(QUrl(enclosureUrl));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QString FvAvailableUpdate::GetEnclosureVersion() const
|
||||
{
|
||||
return m_enclosureVersion;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvAvailableUpdate::SetEnclosureVersion(const QString &enclosureVersion)
|
||||
{
|
||||
m_enclosureVersion = enclosureVersion;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QString FvAvailableUpdate::GetEnclosurePlatform() const
|
||||
{
|
||||
return m_enclosurePlatform;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvAvailableUpdate::SetEnclosurePlatform(const QString &enclosurePlatform)
|
||||
{
|
||||
m_enclosurePlatform = enclosurePlatform;
|
||||
}
|
52
src/libs/fervor/fvavailableupdate.h
Normal file
52
src/libs/fervor/fvavailableupdate.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/***************************************************************************************************
|
||||
**
|
||||
** Copyright (c) 2012 Linas Valiukas and others.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
** software and associated documentation files (the "Software"), to deal in the Software
|
||||
** without restriction, including without limitation the rights to use, copy, modify,
|
||||
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included in all copies or
|
||||
** substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
******************************************************************************************************/
|
||||
|
||||
#ifndef FVAVAILABLEUPDATE_H
|
||||
#define FVAVAILABLEUPDATE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
class FvAvailableUpdate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FvAvailableUpdate(QObject *parent = nullptr);
|
||||
|
||||
QUrl GetEnclosureUrl() const;
|
||||
void SetEnclosureUrl(const QUrl &enclosureUrl);
|
||||
void SetEnclosureUrl(const QString &enclosureUrl);
|
||||
|
||||
QString GetEnclosureVersion() const;
|
||||
void SetEnclosureVersion(const QString &enclosureVersion);
|
||||
|
||||
QString GetEnclosurePlatform() const;
|
||||
void SetEnclosurePlatform(const QString &enclosurePlatform);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(FvAvailableUpdate)
|
||||
|
||||
QUrl m_enclosureUrl;
|
||||
QString m_enclosureVersion;
|
||||
QString m_enclosurePlatform;
|
||||
};
|
||||
|
||||
#endif // FVAVAILABLEUPDATE_H
|
589
src/libs/fervor/fvupdater.cpp
Normal file
589
src/libs/fervor/fvupdater.cpp
Normal file
|
@ -0,0 +1,589 @@
|
|||
/***************************************************************************************************
|
||||
**
|
||||
** Copyright (c) 2012 Linas Valiukas and others.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
** software and associated documentation files (the "Software"), to deal in the Software
|
||||
** without restriction, including without limitation the rights to use, copy, modify,
|
||||
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included in all copies or
|
||||
** substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
******************************************************************************************************/
|
||||
|
||||
#include "fvupdater.h"
|
||||
#include "../vmisc/projectversion.h"
|
||||
#include "../vmisc/vabstractapplication.h"
|
||||
#include "../ifc/xml/vabstractconverter.h"
|
||||
#include "../ifc/exception/vexception.h"
|
||||
|
||||
#include <QtNetwork>
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QDebug>
|
||||
|
||||
QPointer<FvUpdater> FvUpdater::m_Instance;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
FvUpdater* FvUpdater::sharedUpdater()
|
||||
{
|
||||
static QMutex mutex;
|
||||
if (m_Instance.isNull())
|
||||
{
|
||||
mutex.lock();
|
||||
|
||||
if (m_Instance.isNull())
|
||||
{
|
||||
m_Instance = new FvUpdater;
|
||||
}
|
||||
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
return m_Instance.data();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::drop()
|
||||
{
|
||||
static QMutex mutex;
|
||||
mutex.lock();
|
||||
delete m_Instance;
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
FvUpdater::FvUpdater()
|
||||
: QObject(nullptr),
|
||||
m_updaterWindow(nullptr),
|
||||
m_proposedUpdate(nullptr),
|
||||
m_silentAsMuchAsItCouldGet(true),
|
||||
m_feedURL(),
|
||||
m_qnam(),
|
||||
m_reply(nullptr),
|
||||
m_httpRequestAborted(false),
|
||||
m_xml()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
FvUpdater::~FvUpdater()
|
||||
{
|
||||
hideUpdaterWindow();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::showUpdaterWindowUpdatedWithCurrentUpdateProposal()
|
||||
{
|
||||
// Destroy window if already exists
|
||||
hideUpdaterWindow();
|
||||
|
||||
// Create a new window
|
||||
m_updaterWindow = new FvUpdateWindow(qApp->getMainWindow());
|
||||
m_updaterWindow->UpdateWindowWithCurrentProposedUpdate();
|
||||
m_updaterWindow->show();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::hideUpdaterWindow()
|
||||
{
|
||||
if (m_updaterWindow)
|
||||
{
|
||||
m_updaterWindow->close();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::SetFeedURL(const QUrl &feedURL)
|
||||
{
|
||||
m_feedURL = feedURL;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::SetFeedURL(const QString &feedURL)
|
||||
{
|
||||
SetFeedURL(QUrl(feedURL));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QString FvUpdater::GetFeedURL() const
|
||||
{
|
||||
return m_feedURL.toString();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPointer<FvAvailableUpdate> FvUpdater::GetProposedUpdate()
|
||||
{
|
||||
return m_proposedUpdate;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::InstallUpdate()
|
||||
{
|
||||
qDebug() << "Install update";
|
||||
|
||||
UpdateInstallationConfirmed();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::SkipUpdate()
|
||||
{
|
||||
qDebug() << "Skip update";
|
||||
|
||||
FvAvailableUpdate* proposedUpdate = GetProposedUpdate();
|
||||
if (not proposedUpdate)
|
||||
{
|
||||
qWarning() << "Proposed update is NULL (shouldn't be at this point)";
|
||||
return;
|
||||
}
|
||||
|
||||
// Start ignoring this particular version
|
||||
IgnoreVersion(proposedUpdate->GetEnclosureVersion());
|
||||
|
||||
hideUpdaterWindow();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::RemindMeLater()
|
||||
{
|
||||
qDebug() << "Remind me later";
|
||||
|
||||
hideUpdaterWindow();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::UpdateInstallationConfirmed()
|
||||
{
|
||||
qDebug() << "Confirm update installation";
|
||||
|
||||
QPointer<FvAvailableUpdate> proposedUpdate = GetProposedUpdate();
|
||||
if (proposedUpdate.isNull())
|
||||
{
|
||||
qWarning() << "Proposed update is NULL (shouldn't be at this point)";
|
||||
return;
|
||||
}
|
||||
|
||||
// Open a link
|
||||
if (not QDesktopServices::openUrl(proposedUpdate->GetEnclosureUrl()))
|
||||
{
|
||||
showErrorDialog(tr("Unable to open a browser."), true);
|
||||
return;
|
||||
}
|
||||
|
||||
hideUpdaterWindow();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdater::CheckForUpdates(bool silentAsMuchAsItCouldGet)
|
||||
{
|
||||
if (m_feedURL.isEmpty())
|
||||
{
|
||||
qCritical() << "Please set feed URL via setFeedURL() before calling CheckForUpdates().";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_silentAsMuchAsItCouldGet = silentAsMuchAsItCouldGet;
|
||||
|
||||
// Check if application's organization name and domain are set, fail otherwise
|
||||
// (nowhere to store QSettings to)
|
||||
if (QApplication::organizationName().isEmpty())
|
||||
{
|
||||
qCritical() << "QApplication::organizationName is not set. Please do that.";
|
||||
return false;
|
||||
}
|
||||
if (QApplication::organizationDomain().isEmpty())
|
||||
{
|
||||
qCritical() << "QApplication::organizationDomain is not set. Please do that.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set application name / version is not set yet
|
||||
if (QApplication::applicationName().isEmpty())
|
||||
{
|
||||
qCritical() << "QApplication::applicationName is not set. Please do that.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (QApplication::applicationVersion().isEmpty())
|
||||
{
|
||||
qCritical() << "QApplication::applicationVersion is not set. Please do that.";
|
||||
return false;
|
||||
}
|
||||
|
||||
cancelDownloadFeed();
|
||||
m_httpRequestAborted = false;
|
||||
startDownloadFeed(m_feedURL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdater::CheckForUpdatesSilent()
|
||||
{
|
||||
return CheckForUpdates(true);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdater::CheckForUpdatesNotSilent()
|
||||
{
|
||||
return CheckForUpdates(false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::startDownloadFeed(const QUrl &url)
|
||||
{
|
||||
m_xml.clear();
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/xml"));
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, QApplication::applicationName());
|
||||
request.setUrl(url);
|
||||
|
||||
m_reply = m_qnam.get(request);
|
||||
|
||||
connect(m_reply, &QNetworkReply::readyRead, this, &FvUpdater::httpFeedReadyRead);
|
||||
connect(m_reply, &QNetworkReply::downloadProgress, this, &FvUpdater::httpFeedUpdateDataReadProgress);
|
||||
connect(m_reply, &QNetworkReply::finished, this, &FvUpdater::httpFeedDownloadFinished);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::cancelDownloadFeed()
|
||||
{
|
||||
if (m_reply)
|
||||
{
|
||||
m_httpRequestAborted = true;
|
||||
m_reply->abort();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::httpFeedReadyRead()
|
||||
{
|
||||
// this slot gets called every time the QNetworkReply has new data.
|
||||
// We read all of its new data and write it into the file.
|
||||
// That way we use less RAM than when reading it at the finished()
|
||||
// signal of the QNetworkReply
|
||||
m_xml.addData(m_reply->readAll());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::httpFeedUpdateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
|
||||
{
|
||||
Q_UNUSED(bytesRead);
|
||||
Q_UNUSED(totalBytes);
|
||||
|
||||
if (m_httpRequestAborted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::httpFeedDownloadFinished()
|
||||
{
|
||||
if (m_httpRequestAborted)
|
||||
{
|
||||
m_reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const QVariant redirectionTarget = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
||||
if (m_reply->error())
|
||||
{
|
||||
// Error.
|
||||
showErrorDialog(tr("Feed download failed: %1.").arg(m_reply->errorString()), false);
|
||||
}
|
||||
else if (not redirectionTarget.isNull())
|
||||
{
|
||||
const QUrl newUrl = m_feedURL.resolved(redirectionTarget.toUrl());
|
||||
|
||||
m_feedURL = newUrl;
|
||||
m_reply->deleteLater();
|
||||
|
||||
startDownloadFeed(m_feedURL);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Done.
|
||||
xmlParseFeed();
|
||||
}
|
||||
|
||||
m_reply->deleteLater();
|
||||
m_reply = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdater::xmlParseFeed()
|
||||
{
|
||||
QString xmlEnclosureUrl, xmlEnclosureVersion, xmlEnclosurePlatform;
|
||||
|
||||
// Parse
|
||||
while (not m_xml.atEnd())
|
||||
{
|
||||
m_xml.readNext();
|
||||
|
||||
if (m_xml.isStartElement())
|
||||
{
|
||||
if (m_xml.name() == QLatin1Literal("item"))
|
||||
{
|
||||
xmlEnclosureUrl.clear();
|
||||
xmlEnclosureVersion.clear();
|
||||
xmlEnclosurePlatform.clear();
|
||||
}
|
||||
else if (m_xml.name() == QLatin1Literal("enclosure"))
|
||||
{
|
||||
const QXmlStreamAttributes attribs = m_xml.attributes();
|
||||
const QString fervorPlatform = QStringLiteral("fervor:platform");
|
||||
|
||||
if (attribs.hasAttribute(fervorPlatform))
|
||||
{
|
||||
if (CurrentlyRunningOnPlatform(attribs.value(fervorPlatform).toString().trimmed()))
|
||||
{
|
||||
xmlEnclosurePlatform = attribs.value(fervorPlatform).toString().trimmed();
|
||||
|
||||
const QString attributeUrl = QStringLiteral("url");
|
||||
if (attribs.hasAttribute(attributeUrl))
|
||||
{
|
||||
xmlEnclosureUrl = attribs.value(attributeUrl).toString().trimmed();
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlEnclosureUrl.clear();
|
||||
}
|
||||
|
||||
const QString fervorVersion = QStringLiteral("fervor:version");
|
||||
if (attribs.hasAttribute(fervorVersion))
|
||||
{
|
||||
const QString candidateVersion = attribs.value(fervorVersion).toString().trimmed();
|
||||
if (not candidateVersion.isEmpty())
|
||||
{
|
||||
xmlEnclosureVersion = candidateVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_xml.isEndElement())
|
||||
{
|
||||
if (m_xml.name() == QLatin1Literal("item"))
|
||||
{
|
||||
// That's it - we have analyzed a single <item> and we'll stop
|
||||
// here (because the topmost is the most recent one, and thus
|
||||
// the newest version.
|
||||
|
||||
return searchDownloadedFeedForUpdates(xmlEnclosureUrl,
|
||||
xmlEnclosureVersion,
|
||||
xmlEnclosurePlatform);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_xml.error() && m_xml.error() != QXmlStreamReader::PrematureEndOfDocumentError)
|
||||
{
|
||||
showErrorDialog(tr("Feed parsing failed: %1 %2.").arg(QString::number(m_xml.lineNumber()),
|
||||
m_xml.errorString()), false);
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// No updates were found if we're at this point
|
||||
// (not a single <item> element found)
|
||||
showInformationDialog(tr("No updates were found."), false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdater::searchDownloadedFeedForUpdates(const QString &xmlEnclosureUrl,
|
||||
const QString &xmlEnclosureVersion,
|
||||
const QString &xmlEnclosurePlatform)
|
||||
{
|
||||
qDebug() << "Enclosure URL:" << xmlEnclosureUrl;
|
||||
qDebug() << "Enclosure version:" << xmlEnclosureVersion;
|
||||
qDebug() << "Enclosure platform:" << xmlEnclosurePlatform;
|
||||
|
||||
// Validate
|
||||
if (xmlEnclosureUrl.isEmpty() || xmlEnclosureVersion.isEmpty() || xmlEnclosurePlatform.isEmpty())
|
||||
{
|
||||
showErrorDialog(tr("Feed error: invalid \"enclosure\" with the download link"), false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Relevant version?
|
||||
if (VersionIsIgnored(xmlEnclosureVersion))
|
||||
{
|
||||
qDebug() << "Version '" << xmlEnclosureVersion << "' is ignored, too old or something like that.";
|
||||
|
||||
showInformationDialog(tr("No updates were found."), false);
|
||||
|
||||
return true; // Things have succeeded when you think of it.
|
||||
}
|
||||
|
||||
//
|
||||
// Success! At this point, we have found an update that can be proposed
|
||||
// to the user.
|
||||
//
|
||||
|
||||
if (m_proposedUpdate)
|
||||
{
|
||||
delete m_proposedUpdate;
|
||||
}
|
||||
m_proposedUpdate = new FvAvailableUpdate(this);
|
||||
m_proposedUpdate->SetEnclosureUrl(xmlEnclosureUrl);
|
||||
m_proposedUpdate->SetEnclosureVersion(xmlEnclosureVersion);
|
||||
m_proposedUpdate->SetEnclosurePlatform(xmlEnclosurePlatform);
|
||||
|
||||
// Show "look, there's an update" window
|
||||
showUpdaterWindowUpdatedWithCurrentUpdateProposal();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdater::VersionIsIgnored(const QString &version)
|
||||
{
|
||||
// We assume that variable 'version' contains either:
|
||||
// 1) The current version of the application (ignore)
|
||||
// 2) The version that was skipped before and thus stored in QSettings (ignore)
|
||||
// 3) A newer version (don't ignore)
|
||||
// 'version' is not likely to contain an older version in any case.
|
||||
|
||||
int decVersion = 0x0;
|
||||
try
|
||||
{
|
||||
decVersion = VAbstractConverter::GetVersion(version);
|
||||
}
|
||||
catch (const VException &e)
|
||||
{
|
||||
Q_UNUSED(e)
|
||||
return true; // Ignore invalid version
|
||||
}
|
||||
|
||||
if (decVersion == APP_VERSION)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const int lastSkippedVersion = qApp->Settings()->GetLatestSkippedVersion();
|
||||
if (lastSkippedVersion != 0x0)
|
||||
{
|
||||
if (decVersion == lastSkippedVersion)
|
||||
{
|
||||
// Implicitly skipped version - skip
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (decVersion > APP_VERSION)
|
||||
{
|
||||
// Newer version - do not skip
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fallback - skip
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::IgnoreVersion(const QString &version)
|
||||
{
|
||||
int decVersion = 0x0;
|
||||
try
|
||||
{
|
||||
decVersion = VAbstractConverter::GetVersion(version);
|
||||
}
|
||||
catch (const VException &e)
|
||||
{
|
||||
Q_UNUSED(e)
|
||||
return ; // Ignore invalid version
|
||||
}
|
||||
|
||||
if (decVersion == APP_VERSION)
|
||||
{
|
||||
// Don't ignore the current version
|
||||
return;
|
||||
}
|
||||
|
||||
qApp->Settings()->SetLatestSkippedVersion(decVersion);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdater::CurrentlyRunningOnPlatform(const QString &platform)
|
||||
{
|
||||
const QStringList platforms = QStringList() << "Q_OS_LINUX"
|
||||
<< "Q_OS_MAC"
|
||||
<< "Q_OS_WIN32";
|
||||
|
||||
switch (platforms.indexOf(platform.toUpper().trimmed()))
|
||||
{
|
||||
case 0: // Q_OS_LINUX
|
||||
#ifdef Q_OS_LINUX // Defined on Linux.
|
||||
return true;
|
||||
#endif
|
||||
break;
|
||||
case 1: // Q_OS_MAC
|
||||
#ifdef Q_OS_MAC // Defined on MAC OS (synonym for Darwin).
|
||||
return true;
|
||||
#endif
|
||||
break;
|
||||
case 2: // Q_OS_WIN32
|
||||
#ifdef Q_OS_WIN32 // Defined on all supported versions of Windows.
|
||||
return true;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::showErrorDialog(const QString &message, bool showEvenInSilentMode)
|
||||
{
|
||||
if (m_silentAsMuchAsItCouldGet)
|
||||
{
|
||||
if (not showEvenInSilentMode)
|
||||
{
|
||||
// Don't show errors in the silent mode
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QMessageBox dlFailedMsgBox;
|
||||
dlFailedMsgBox.setIcon(QMessageBox::Critical);
|
||||
dlFailedMsgBox.setText(tr("Error"));
|
||||
dlFailedMsgBox.setInformativeText(message);
|
||||
dlFailedMsgBox.exec();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void FvUpdater::showInformationDialog(const QString &message, bool showEvenInSilentMode)
|
||||
{
|
||||
if (m_silentAsMuchAsItCouldGet)
|
||||
{
|
||||
if (not showEvenInSilentMode)
|
||||
{
|
||||
// Don't show information dialogs in the silent mode
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QMessageBox dlInformationMsgBox;
|
||||
dlInformationMsgBox.setIcon(QMessageBox::Information);
|
||||
dlInformationMsgBox.setText(tr("Information"));
|
||||
dlInformationMsgBox.setInformativeText(message);
|
||||
dlInformationMsgBox.exec();
|
||||
}
|
128
src/libs/fervor/fvupdater.h
Normal file
128
src/libs/fervor/fvupdater.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/***************************************************************************************************
|
||||
**
|
||||
** Copyright (c) 2012 Linas Valiukas and others.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
** software and associated documentation files (the "Software"), to deal in the Software
|
||||
** without restriction, including without limitation the rights to use, copy, modify,
|
||||
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included in all copies or
|
||||
** substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
******************************************************************************************************/
|
||||
|
||||
#ifndef FVUPDATER_H
|
||||
#define FVUPDATER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QUrl>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QPointer>
|
||||
|
||||
#include "fvupdatewindow.h"
|
||||
#include "fvavailableupdate.h"
|
||||
|
||||
class FvUpdater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Singleton
|
||||
static FvUpdater* sharedUpdater();
|
||||
static void drop();
|
||||
|
||||
// Set / get feed URL
|
||||
void SetFeedURL(const QUrl &feedURL);
|
||||
void SetFeedURL(const QString &feedURL);
|
||||
QString GetFeedURL() const;
|
||||
|
||||
public slots:
|
||||
// Check for updates
|
||||
bool CheckForUpdates(bool silentAsMuchAsItCouldGet = true);
|
||||
|
||||
// Aliases
|
||||
bool CheckForUpdatesSilent();
|
||||
bool CheckForUpdatesNotSilent();
|
||||
|
||||
protected:
|
||||
friend class FvUpdateWindow; // Uses GetProposedUpdate() and others
|
||||
QPointer<FvAvailableUpdate> GetProposedUpdate();
|
||||
|
||||
protected slots:
|
||||
// Update window button slots
|
||||
void InstallUpdate();
|
||||
void SkipUpdate();
|
||||
void RemindMeLater();
|
||||
|
||||
// Update confirmation dialog button slots
|
||||
void UpdateInstallationConfirmed();
|
||||
|
||||
private slots:
|
||||
void httpFeedReadyRead();
|
||||
void httpFeedUpdateDataReadProgress(qint64 bytesRead, qint64 totalBytes);
|
||||
void httpFeedDownloadFinished();
|
||||
|
||||
private:
|
||||
//
|
||||
// Singleton business
|
||||
//
|
||||
Q_DISABLE_COPY(FvUpdater)
|
||||
FvUpdater(); // Hide main constructor
|
||||
virtual ~FvUpdater(); // Hide main destructor
|
||||
|
||||
static QPointer<FvUpdater> m_Instance; // Singleton instance
|
||||
|
||||
QPointer<FvUpdateWindow> m_updaterWindow; // Updater window (NULL if not shown)
|
||||
|
||||
// Available update (NULL if not fetched)
|
||||
QPointer<FvAvailableUpdate> m_proposedUpdate;
|
||||
|
||||
// If true, don't show the error dialogs and the "no updates." dialog
|
||||
// (silentAsMuchAsItCouldGet from CheckForUpdates() goes here)
|
||||
// Useful for automatic update checking upon application startup.
|
||||
bool m_silentAsMuchAsItCouldGet;
|
||||
|
||||
//
|
||||
// HTTP feed fetcher infrastructure
|
||||
//
|
||||
QUrl m_feedURL; // Feed URL that will be fetched
|
||||
QNetworkAccessManager m_qnam;
|
||||
QNetworkReply* m_reply;
|
||||
bool m_httpRequestAborted;
|
||||
|
||||
QXmlStreamReader m_xml; // XML data collector and parser
|
||||
|
||||
void showUpdaterWindowUpdatedWithCurrentUpdateProposal(); // Show updater window
|
||||
void hideUpdaterWindow(); // Hide + destroy m_updaterWindow
|
||||
|
||||
void startDownloadFeed(const QUrl &url); // Start downloading feed
|
||||
void cancelDownloadFeed(); // Stop downloading the current feed
|
||||
|
||||
// Dialogs (notifications)
|
||||
// Show an error message
|
||||
void showErrorDialog(const QString &message, bool showEvenInSilentMode = false);
|
||||
// Show an informational message
|
||||
void showInformationDialog(const QString &message, bool showEvenInSilentMode = false);
|
||||
|
||||
|
||||
bool xmlParseFeed(); // Parse feed in m_xml
|
||||
bool searchDownloadedFeedForUpdates(const QString &xmlEnclosureUrl,
|
||||
const QString &xmlEnclosureVersion,
|
||||
const QString &xmlEnclosurePlatform);
|
||||
|
||||
static bool VersionIsIgnored(const QString &version);
|
||||
static void IgnoreVersion(const QString &version);
|
||||
static bool CurrentlyRunningOnPlatform(const QString &platform);
|
||||
};
|
||||
|
||||
#endif // FVUPDATER_H
|
72
src/libs/fervor/fvupdatewindow.cpp
Normal file
72
src/libs/fervor/fvupdatewindow.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************************************
|
||||
**
|
||||
** Copyright (c) 2012 Linas Valiukas and others.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
** software and associated documentation files (the "Software"), to deal in the Software
|
||||
** without restriction, including without limitation the rights to use, copy, modify,
|
||||
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included in all copies or
|
||||
** substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
******************************************************************************************************/
|
||||
|
||||
#include "fvupdatewindow.h"
|
||||
#include "ui_fvupdatewindow.h"
|
||||
#include "fvupdater.h"
|
||||
#include "fvavailableupdate.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCloseEvent>
|
||||
#include <QDebug>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
FvUpdateWindow::FvUpdateWindow(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
m_ui(new Ui::FvUpdateWindow),
|
||||
m_appIconScene(nullptr)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
// Delete on close
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
||||
// Set the "new version is available" string
|
||||
const QString newVersString = m_ui->newVersionIsAvailableLabel->text().arg(qApp->applicationDisplayName());
|
||||
m_ui->newVersionIsAvailableLabel->setText(newVersString);
|
||||
|
||||
// Connect buttons
|
||||
connect(m_ui->installUpdateButton, &QPushButton::clicked, FvUpdater::sharedUpdater(), &FvUpdater::InstallUpdate);
|
||||
connect(m_ui->skipThisVersionButton, &QPushButton::clicked, FvUpdater::sharedUpdater(), &FvUpdater::SkipUpdate);
|
||||
connect(m_ui->remindMeLaterButton, &QPushButton::clicked, FvUpdater::sharedUpdater(), &FvUpdater::RemindMeLater);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
FvUpdateWindow::~FvUpdateWindow()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool FvUpdateWindow::UpdateWindowWithCurrentProposedUpdate()
|
||||
{
|
||||
QPointer<FvAvailableUpdate> proposedUpdate = FvUpdater::sharedUpdater()->GetProposedUpdate();
|
||||
if (proposedUpdate.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString downloadString = m_ui->wouldYouLikeToDownloadLabel->text()
|
||||
.arg(qApp->applicationDisplayName(), proposedUpdate->GetEnclosureVersion(), qApp->applicationVersion());
|
||||
m_ui->wouldYouLikeToDownloadLabel->setText(downloadString);
|
||||
|
||||
return true;
|
||||
}
|
53
src/libs/fervor/fvupdatewindow.h
Normal file
53
src/libs/fervor/fvupdatewindow.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/***************************************************************************************************
|
||||
**
|
||||
** Copyright (c) 2012 Linas Valiukas and others.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
** software and associated documentation files (the "Software"), to deal in the Software
|
||||
** without restriction, including without limitation the rights to use, copy, modify,
|
||||
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included in all copies or
|
||||
** substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
******************************************************************************************************/
|
||||
|
||||
#ifndef FVUPDATEWINDOW_H
|
||||
#define FVUPDATEWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QGraphicsScene;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FvUpdateWindow;
|
||||
}
|
||||
|
||||
class FvUpdateWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FvUpdateWindow(QWidget *parent = nullptr);
|
||||
virtual ~FvUpdateWindow();
|
||||
|
||||
// Update the current update proposal from FvUpdater
|
||||
bool UpdateWindowWithCurrentProposedUpdate();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(FvUpdateWindow)
|
||||
|
||||
Ui::FvUpdateWindow* m_ui;
|
||||
QGraphicsScene* m_appIconScene;
|
||||
|
||||
};
|
||||
|
||||
#endif // FVUPDATEWINDOW_H
|
98
src/libs/fervor/fvupdatewindow.ui
Normal file
98
src/libs/fervor/fvupdatewindow.ui
Normal file
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FvUpdateWindow</class>
|
||||
<widget class="QDialog" name="FvUpdateWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>520</width>
|
||||
<height>95</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Software Update</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../vmisc/share/resources/icon.qrc">
|
||||
<normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="newVersionIsAvailableLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>A new version of %1 is available!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="wouldYouLikeToDownloadLabel">
|
||||
<property name="text">
|
||||
<string>%1 %2 is now available - you have %3. Would you like to download it now?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="skipThisVersionButton">
|
||||
<property name="text">
|
||||
<string>Skip This Version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="remindMeLaterButton">
|
||||
<property name="text">
|
||||
<string>Remind Me Later</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="installUpdateButton">
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Get Update</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../vmisc/share/resources/icon.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -33,6 +33,7 @@
|
|||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QRegularExpression>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VAbstractConverter::VAbstractConverter(const QString &fileName)
|
||||
|
@ -107,7 +108,7 @@ QString VAbstractConverter::GetVersionStr() const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
int VAbstractConverter::GetVersion(const QString &version) const
|
||||
int VAbstractConverter::GetVersion(const QString &version)
|
||||
{
|
||||
ValidateVersion(version);
|
||||
|
||||
|
@ -138,11 +139,11 @@ int VAbstractConverter::GetVersion(const QString &version) const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VAbstractConverter::ValidateVersion(const QString &version) const
|
||||
void VAbstractConverter::ValidateVersion(const QString &version)
|
||||
{
|
||||
const QRegExp rx(QStringLiteral("^(0|([1-9][0-9]*)).(0|([1-9][0-9]*)).(0|([1-9][0-9]*))$"));
|
||||
const QRegularExpression rx(QStringLiteral("^(0|([1-9][0-9]*)).(0|([1-9][0-9]*)).(0|([1-9][0-9]*))$"));
|
||||
|
||||
if (rx.exactMatch(version) == false)
|
||||
if (rx.match(version).hasMatch() == false)
|
||||
{
|
||||
const QString errorMsg(tr("Version \"%1\" invalid.").arg(version));
|
||||
throw VException(errorMsg);
|
||||
|
|
|
@ -43,12 +43,13 @@ public:
|
|||
void Convert();
|
||||
virtual bool SaveDocument(const QString &fileName, QString &error) const Q_DECL_OVERRIDE;
|
||||
|
||||
static int GetVersion(const QString &version);
|
||||
|
||||
protected:
|
||||
int ver;
|
||||
QString fileName;
|
||||
|
||||
void ValidateInputFile(const QString ¤tSchema) const;
|
||||
int GetVersion(const QString &version) const;
|
||||
Q_NORETURN void InvalidVersion(int ver) const;
|
||||
void Save() const;
|
||||
void SetVersion(const QString &version);
|
||||
|
@ -72,7 +73,7 @@ private:
|
|||
|
||||
QString GetVersionStr() const;
|
||||
|
||||
void ValidateVersion(const QString &version) const;
|
||||
static void ValidateVersion(const QString &version);
|
||||
|
||||
void ReserveFile() const;
|
||||
};
|
||||
|
|
|
@ -11,4 +11,5 @@ SUBDIRS = \
|
|||
vmisc \
|
||||
vwidgets \
|
||||
vtools \
|
||||
vformat
|
||||
vformat \
|
||||
fervor
|
||||
|
|
|
@ -65,6 +65,7 @@ const QString VCommonSettings::SettingGeneralGeometry = QString
|
|||
const QString VCommonSettings::SettingGeneralWindowState = QStringLiteral("windowState");
|
||||
const QString VCommonSettings::SettingGeneralToolbarsState = QStringLiteral("toolbarsState");
|
||||
const QString VCommonSettings::SettingPreferenceDialogSize = QStringLiteral("preferenceDialogSize");
|
||||
const QString VCommonSettings::SettingLatestSkippedVersion = QStringLiteral("lastestSkippedVersion");
|
||||
|
||||
static const QString commonIniFilename = QStringLiteral("common");
|
||||
|
||||
|
@ -429,3 +430,15 @@ void VCommonSettings::SetPreferenceDialogSize(const QSize& sz)
|
|||
{
|
||||
setValue(SettingPreferenceDialogSize, sz);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
int VCommonSettings::GetLatestSkippedVersion() const
|
||||
{
|
||||
return value(SettingLatestSkippedVersion, 0x0).toInt();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VCommonSettings::SetLatestSkippedVersion(int value)
|
||||
{
|
||||
setValue(SettingLatestSkippedVersion, value);
|
||||
}
|
||||
|
|
|
@ -99,8 +99,11 @@ public:
|
|||
QByteArray GetToolbarsState() const;
|
||||
void SetToolbarsState(const QByteArray &value);
|
||||
|
||||
QSize GetPreferenceDialogSize() const;
|
||||
void SetPreferenceDialogSize(const QSize& sz);
|
||||
QSize GetPreferenceDialogSize() const;
|
||||
void SetPreferenceDialogSize(const QSize& sz);
|
||||
|
||||
int GetLatestSkippedVersion() const;
|
||||
void SetLatestSkippedVersion(int value);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VCommonSettings)
|
||||
|
@ -128,6 +131,7 @@ private:
|
|||
static const QString SettingGeneralWindowState;
|
||||
static const QString SettingGeneralToolbarsState;
|
||||
static const QString SettingPreferenceDialogSize;
|
||||
static const QString SettingLatestSkippedVersion;
|
||||
};
|
||||
|
||||
#endif // VCOMMONSETTINGS_H
|
||||
|
|
Loading…
Reference in New Issue
Block a user