A lot of changes
- Added qDoc support - Implemented a progress dialog while checking for updates - Automatically show a message box when an update is found or when you have the latest version
This commit is contained in:
parent
de00c961e5
commit
db79a3071d
@ -3,6 +3,7 @@
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName("QSimpleUpdater Example");
|
||||
|
||||
// Create the dialog and show it
|
||||
Example example;
|
||||
@ -69,6 +70,10 @@ void Example::checkForUpdates() {
|
||||
// Tell the updater where to download the update, its recommended to use direct links
|
||||
updater->setDownloadUrl("https://codeload.github.com/alex-97/QSimpleUpdater/zip/master");
|
||||
|
||||
// Show the progress dialog and show messages when checking is finished
|
||||
updater->setSilent(false);
|
||||
updater->setShowNewestVersionMessage(true);
|
||||
|
||||
// Finally, check for updates...
|
||||
updater->checkForUpdates();
|
||||
}
|
||||
@ -78,36 +83,4 @@ void Example::onCheckingFinished() {
|
||||
// that he/she can check for updates again
|
||||
ui->updatesButton->setEnabled(true);
|
||||
ui->updatesButton->setText("Check for updates");
|
||||
|
||||
// There's a newer version of the application available, so we inform
|
||||
// the user that there's a newer version available and we replace the text
|
||||
// of the changelog text edit with the downloaded change log
|
||||
if (updater->newerVersionAvailable()) {
|
||||
ui->changelogTextEdit->setPlainText(updater->changeLog());
|
||||
|
||||
// Create and configure a message box
|
||||
QMessageBox _messagebox;
|
||||
_messagebox.setIcon(QMessageBox::Information);
|
||||
_messagebox.setWindowTitle(tr("Update available"));
|
||||
_messagebox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
_messagebox.setText(tr("There's an update available!"));
|
||||
_messagebox.setInformativeText(tr("The latest version of the application is") + " " +
|
||||
updater->latestVersion() + ", " +
|
||||
tr("do you want to download it?"));
|
||||
|
||||
// If the user clicks "yes" open the download dialog
|
||||
if (_messagebox.exec() == QMessageBox::Yes)
|
||||
updater->downloadLatestVersion();
|
||||
}
|
||||
|
||||
// The installed version is equal or greater to the "official" latest version,
|
||||
// so we inform the user and clear the text of the change log text edit
|
||||
else {
|
||||
ui->changelogTextEdit->setPlainText("");
|
||||
ui->changelogTextEdit->setPlainText("The change log was not downloaded because you "
|
||||
"are running the latest version of the application...");
|
||||
|
||||
QMessageBox::information(this, tr("No updates available"),
|
||||
tr("Congratulations! You are running the latest version of the application!"));
|
||||
}
|
||||
}
|
||||
|
14
QSimpleUpdater/doc/QSimpleUpdater.qdocconf
Normal file
14
QSimpleUpdater/doc/QSimpleUpdater.qdocconf
Normal file
@ -0,0 +1,14 @@
|
||||
# Project info
|
||||
project = QSimpleUpdater
|
||||
url = http://qsimpleupdater.sf.net/doc
|
||||
description = A simple auto-updating system for Qt projects
|
||||
|
||||
# Import sources and headers
|
||||
headerdirs = ../src
|
||||
sourcedirs = ../src
|
||||
sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
|
||||
headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx"
|
||||
|
||||
# Output as HTML
|
||||
outputdir = doc-html
|
||||
outputformats = HTML
|
@ -1,165 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
@ -11,10 +11,12 @@ QT += widgets
|
||||
QT += network
|
||||
|
||||
HEADERS += $$PWD/src/qsimpleupdater.h \
|
||||
$$PWD/src/dialogs/download_dialog.h
|
||||
$$PWD/src/dialogs/download_dialog.h \
|
||||
$$PWD/src/dialogs/progress_dialog.h
|
||||
|
||||
SOURCES += $$PWD/src/qsimpleupdater.cpp \
|
||||
$$PWD/src/dialogs/download_dialog.cpp
|
||||
$$PWD/src/dialogs/download_dialog.cpp \
|
||||
$$PWD/src/dialogs/progress_dialog.cpp
|
||||
|
||||
OTHER_FILES += $$PWD/src/QSimpleUpdater
|
||||
|
||||
@ -30,4 +32,5 @@ win32* {
|
||||
|
||||
RESOURCES += $$PWD/res/qsu_resources.qrc
|
||||
|
||||
FORMS += $$PWD/src/dialogs/download_dialog.ui
|
||||
FORMS += $$PWD/src/dialogs/download_dialog.ui \
|
||||
$$PWD/src/dialogs/progress_dialog.ui
|
||||
|
@ -1,32 +0,0 @@
|
||||
--------------
|
||||
PREFACE
|
||||
--------------
|
||||
|
||||
Many websites today use the HTTPS protocol, which means that you will need SSL in order to communicate with them. If your project needs to access such a webiste (for example GitHub), you will need to carefully read the following information in order to ensure that QSimpleUpdater works with those websites (both in your machine and in the final users' machine).
|
||||
|
||||
This readme guide is extremely important for any developer wishing to deploy his or her applications under the Windows platform, because the application will depend on the libraries provided by QSimpleUpdater.
|
||||
|
||||
--------------
|
||||
LINUX
|
||||
--------------
|
||||
|
||||
Make sure that you have installed the following libraries in your system:
|
||||
|
||||
- lssl
|
||||
- lcrypto
|
||||
|
||||
--------------
|
||||
MAC OSX
|
||||
--------------
|
||||
|
||||
The libraries required by QSimpleUpdater are the same as Linux, however, these libraries are installed by default in most Mac OS X installations.
|
||||
|
||||
--------------
|
||||
WINDOWS
|
||||
--------------
|
||||
|
||||
QSimpleUpdater makes use of the OpenSSL-Win32 project, make sure that have it installed and that the project knows where to find them (the default location is C:/OpenSSL-Win32) and that you deploy the following libraries with your compiled project:
|
||||
|
||||
- libeay32.dll
|
||||
- ssleay32.dll
|
||||
|
@ -1,5 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/icons">
|
||||
<file alias="update.png">update.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
<RCC>
|
||||
<qresource prefix="/icons">
|
||||
<file alias="update.png">update.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@ -1,240 +1,240 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "download_dialog.h"
|
||||
#include "ui_download_dialog.h"
|
||||
|
||||
DownloadDialog::DownloadDialog (QWidget *parent)
|
||||
: QWidget (parent)
|
||||
, ui (new Ui::DownloadDialog) {
|
||||
|
||||
// Setup the UI
|
||||
ui->setupUi (this);
|
||||
|
||||
// Make the window look like a dialog
|
||||
QIcon _blank;
|
||||
setWindowIcon (_blank);
|
||||
setWindowModality (Qt::WindowModal);
|
||||
setWindowFlags (Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
|
||||
|
||||
// Connect SIGNALS/SLOTS
|
||||
connect (ui->stopButton, SIGNAL (clicked()), this, SLOT (cancelDownload()));
|
||||
connect (ui->openButton, SIGNAL (clicked()), this, SLOT (installUpdate()));
|
||||
|
||||
// Configure open button
|
||||
ui->openButton->setEnabled (false);
|
||||
ui->openButton->setVisible (false);
|
||||
|
||||
// Initialize the network access manager
|
||||
m_manager = new QNetworkAccessManager (this);
|
||||
|
||||
// Avoid SSL issues
|
||||
connect (m_manager, SIGNAL (sslErrors (QNetworkReply *, QList<QSslError>)), this,
|
||||
SLOT (ignoreSslErrors (QNetworkReply *, QList<QSslError>)));
|
||||
}
|
||||
|
||||
DownloadDialog::~DownloadDialog (void) {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DownloadDialog::beginDownload (const QUrl& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
|
||||
// Reset the UI
|
||||
ui->progressBar->setValue (0);
|
||||
ui->stopButton->setText (tr ("Stop"));
|
||||
ui->downloadLabel->setText (tr ("Downloading updates"));
|
||||
ui->timeLabel->setText (tr ("Time remaining") + ": " + tr ("unknown"));
|
||||
|
||||
// Begin the download
|
||||
m_reply = m_manager->get (QNetworkRequest (url));
|
||||
m_start_time = QDateTime::currentDateTime().toTime_t();
|
||||
|
||||
// Update the progress bar value automatically
|
||||
connect (m_reply, SIGNAL (downloadProgress (qint64, qint64)), this,
|
||||
SLOT (updateProgress (qint64, qint64)));
|
||||
|
||||
// Write the file to the hard disk once the download is finished
|
||||
connect (m_reply, SIGNAL (finished()), this, SLOT (downloadFinished()));
|
||||
|
||||
// Show the dialog
|
||||
showNormal();
|
||||
}
|
||||
|
||||
void DownloadDialog::installUpdate (void) {
|
||||
QMessageBox msg;
|
||||
msg.setIcon (QMessageBox::Question);
|
||||
msg.setText ("<b>" +
|
||||
tr ("To apply the update(s), you must first quit %1")
|
||||
.arg (qApp->applicationName()) +
|
||||
"</b>");
|
||||
msg.setInformativeText (tr ("Do you want to quit %1 now?").arg (qApp->applicationName()));
|
||||
msg.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (msg.exec() == QMessageBox::Yes) {
|
||||
openDownload();
|
||||
qApp->closeAllWindows();
|
||||
}
|
||||
|
||||
else {
|
||||
ui->openButton->setEnabled (true);
|
||||
ui->openButton->setVisible (true);
|
||||
ui->timeLabel->setText (tr ("Click the \"Open\" button to apply the update"));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::openDownload (void) {
|
||||
if (!m_path.isEmpty()) {
|
||||
QString url = m_path;
|
||||
|
||||
if (url.startsWith ("/"))
|
||||
url = "file://" + url;
|
||||
|
||||
else
|
||||
url = "file:///" + url;
|
||||
|
||||
QDesktopServices::openUrl (url);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::cancelDownload (void) {
|
||||
if (!m_reply->isFinished()) {
|
||||
QMessageBox _message;
|
||||
_message.setWindowTitle (tr ("Updater"));
|
||||
_message.setIcon (QMessageBox::Question);
|
||||
_message.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
|
||||
_message.setText (tr ("Are you sure you want to cancel the download?"));
|
||||
|
||||
if (_message.exec() == QMessageBox::Yes) {
|
||||
hide();
|
||||
m_reply->abort();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
hide();
|
||||
}
|
||||
|
||||
void DownloadDialog::downloadFinished (void) {
|
||||
ui->stopButton->setText (tr ("Close"));
|
||||
ui->downloadLabel->setText (tr ("Download complete!"));
|
||||
ui->timeLabel->setText (tr ("The installer will open in a separate window..."));
|
||||
|
||||
QByteArray data = m_reply->readAll();
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
QStringList list = m_reply->url().toString().split ("/");
|
||||
QFile file (QDir::tempPath() + "/" + list.at (list.count() - 1));
|
||||
|
||||
if (file.open (QIODevice::WriteOnly)) {
|
||||
file.write (data);
|
||||
m_path = file.fileName();
|
||||
}
|
||||
|
||||
file.close();
|
||||
installUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::updateProgress (qint64 received, qint64 total) {
|
||||
// We know the size of the download, so we can calculate the progress....
|
||||
if (total > 0 && received > 0) {
|
||||
ui->progressBar->setMinimum (0);
|
||||
ui->progressBar->setMaximum (100);
|
||||
|
||||
int _progress = (int) ((received * 100) / total);
|
||||
ui->progressBar->setValue (_progress);
|
||||
|
||||
QString _total_string;
|
||||
QString _received_string;
|
||||
|
||||
float _total = total;
|
||||
float _received = received;
|
||||
|
||||
if (_total < 1024)
|
||||
_total_string = tr ("%1 bytes").arg (_total);
|
||||
|
||||
else if (_total < 1024 * 1024) {
|
||||
_total = roundNumber (_total / 1024);
|
||||
_total_string = tr ("%1 KB").arg (_total);
|
||||
}
|
||||
|
||||
else {
|
||||
_total = roundNumber (_total / (1024 * 1024));
|
||||
_total_string = tr ("%1 MB").arg (_total);
|
||||
}
|
||||
|
||||
if (_received < 1024)
|
||||
_received_string = tr ("%1 bytes").arg (_received);
|
||||
|
||||
else if (received < 1024 * 1024) {
|
||||
_received = roundNumber (_received / 1024);
|
||||
_received_string = tr ("%1 KB").arg (_received);
|
||||
}
|
||||
|
||||
else {
|
||||
_received = roundNumber (_received / (1024 * 1024));
|
||||
_received_string = tr ("%1 MB").arg (_received);
|
||||
}
|
||||
|
||||
ui->downloadLabel->setText (tr ("Downloading updates") + " (" + _received_string + " " + tr ("of") + " " + _total_string + ")");
|
||||
|
||||
uint _diff = QDateTime::currentDateTime().toTime_t() - m_start_time;
|
||||
|
||||
if (_diff > 0) {
|
||||
QString _time_string;
|
||||
float _time_remaining = total / (received / _diff);
|
||||
|
||||
if (_time_remaining > 7200) {
|
||||
_time_remaining /= 3600;
|
||||
_time_string = tr ("About %1 hours").arg (int (_time_remaining + 0.5));
|
||||
}
|
||||
|
||||
else if (_time_remaining > 60) {
|
||||
_time_remaining /= 60;
|
||||
_time_string = tr ("About %1 minutes").arg (int (_time_remaining + 0.5));
|
||||
}
|
||||
|
||||
else if (_time_remaining <= 60)
|
||||
_time_string = tr ("%1 seconds").arg (int (_time_remaining + 0.5));
|
||||
|
||||
ui->timeLabel->setText (tr ("Time remaining") + ": " + _time_string);
|
||||
}
|
||||
}
|
||||
|
||||
// We do not know the size of the download, so we avoid scaring the shit out
|
||||
// of the user
|
||||
else {
|
||||
ui->progressBar->setValue (-1);
|
||||
ui->progressBar->setMinimum (0);
|
||||
ui->progressBar->setMaximum (0);
|
||||
ui->downloadLabel->setText (tr ("Downloading updates"));
|
||||
ui->timeLabel->setText (tr ("Time remaining") + ": " + tr ("Unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::ignoreSslErrors (QNetworkReply *reply,
|
||||
const QList<QSslError>& error) {
|
||||
#ifndef Q_OS_IOS
|
||||
reply->ignoreSslErrors (error);
|
||||
#else
|
||||
Q_UNUSED (reply);
|
||||
Q_UNUSED (error);
|
||||
#endif
|
||||
}
|
||||
|
||||
float DownloadDialog::roundNumber (const float& input) {
|
||||
return roundf (input * 100) / 100;
|
||||
}
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "download_dialog.h"
|
||||
#include "ui_download_dialog.h"
|
||||
|
||||
DownloadDialog::DownloadDialog (QWidget *parent)
|
||||
: QWidget (parent)
|
||||
, ui (new Ui::DownloadDialog) {
|
||||
|
||||
// Setup the UI
|
||||
ui->setupUi (this);
|
||||
|
||||
// Make the window look like a dialog
|
||||
QIcon _blank;
|
||||
setWindowIcon (_blank);
|
||||
setWindowModality (Qt::WindowModal);
|
||||
setWindowFlags (Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
|
||||
|
||||
// Connect SIGNALS/SLOTS
|
||||
connect (ui->stopButton, SIGNAL (clicked()), this, SLOT (cancelDownload()));
|
||||
connect (ui->openButton, SIGNAL (clicked()), this, SLOT (installUpdate()));
|
||||
|
||||
// Configure open button
|
||||
ui->openButton->setEnabled (false);
|
||||
ui->openButton->setVisible (false);
|
||||
|
||||
// Initialize the network access manager
|
||||
m_manager = new QNetworkAccessManager (this);
|
||||
|
||||
// Avoid SSL issues
|
||||
connect (m_manager, SIGNAL (sslErrors (QNetworkReply *, QList<QSslError>)), this,
|
||||
SLOT (ignoreSslErrors (QNetworkReply *, QList<QSslError>)));
|
||||
}
|
||||
|
||||
DownloadDialog::~DownloadDialog (void) {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DownloadDialog::beginDownload (const QUrl& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
|
||||
// Reset the UI
|
||||
ui->progressBar->setValue (0);
|
||||
ui->stopButton->setText (tr ("Stop"));
|
||||
ui->downloadLabel->setText (tr ("Downloading updates"));
|
||||
ui->timeLabel->setText (tr ("Time remaining") + ": " + tr ("unknown"));
|
||||
|
||||
// Begin the download
|
||||
m_reply = m_manager->get (QNetworkRequest (url));
|
||||
m_start_time = QDateTime::currentDateTime().toTime_t();
|
||||
|
||||
// Update the progress bar value automatically
|
||||
connect (m_reply, SIGNAL (downloadProgress (qint64, qint64)), this,
|
||||
SLOT (updateProgress (qint64, qint64)));
|
||||
|
||||
// Write the file to the hard disk once the download is finished
|
||||
connect (m_reply, SIGNAL (finished()), this, SLOT (downloadFinished()));
|
||||
|
||||
// Show the dialog
|
||||
showNormal();
|
||||
}
|
||||
|
||||
void DownloadDialog::installUpdate (void) {
|
||||
QMessageBox msg;
|
||||
msg.setIcon (QMessageBox::Question);
|
||||
msg.setText ("<b>" +
|
||||
tr ("To apply the update(s), you must first quit %1")
|
||||
.arg (qApp->applicationName()) +
|
||||
"</b>");
|
||||
msg.setInformativeText (tr ("Do you want to quit %1 now?").arg (qApp->applicationName()));
|
||||
msg.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (msg.exec() == QMessageBox::Yes) {
|
||||
openDownload();
|
||||
qApp->closeAllWindows();
|
||||
}
|
||||
|
||||
else {
|
||||
ui->openButton->setEnabled (true);
|
||||
ui->openButton->setVisible (true);
|
||||
ui->timeLabel->setText (tr ("Click the \"Open\" button to apply the update"));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::openDownload (void) {
|
||||
if (!m_path.isEmpty()) {
|
||||
QString url = m_path;
|
||||
|
||||
if (url.startsWith ("/"))
|
||||
url = "file://" + url;
|
||||
|
||||
else
|
||||
url = "file:///" + url;
|
||||
|
||||
QDesktopServices::openUrl (url);
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::cancelDownload (void) {
|
||||
if (!m_reply->isFinished()) {
|
||||
QMessageBox _message;
|
||||
_message.setWindowTitle (tr ("Updater"));
|
||||
_message.setIcon (QMessageBox::Question);
|
||||
_message.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
|
||||
_message.setText (tr ("Are you sure you want to cancel the download?"));
|
||||
|
||||
if (_message.exec() == QMessageBox::Yes) {
|
||||
hide();
|
||||
m_reply->abort();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
hide();
|
||||
}
|
||||
|
||||
void DownloadDialog::downloadFinished (void) {
|
||||
ui->stopButton->setText (tr ("Close"));
|
||||
ui->downloadLabel->setText (tr ("Download complete!"));
|
||||
ui->timeLabel->setText (tr ("The installer will open in a separate window..."));
|
||||
|
||||
QByteArray data = m_reply->readAll();
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
QStringList list = m_reply->url().toString().split ("/");
|
||||
QFile file (QDir::tempPath() + "/" + list.at (list.count() - 1));
|
||||
|
||||
if (file.open (QIODevice::WriteOnly)) {
|
||||
file.write (data);
|
||||
m_path = file.fileName();
|
||||
}
|
||||
|
||||
file.close();
|
||||
installUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::updateProgress (qint64 received, qint64 total) {
|
||||
// We know the size of the download, so we can calculate the progress....
|
||||
if (total > 0 && received > 0) {
|
||||
ui->progressBar->setMinimum (0);
|
||||
ui->progressBar->setMaximum (100);
|
||||
|
||||
int _progress = (int) ((received * 100) / total);
|
||||
ui->progressBar->setValue (_progress);
|
||||
|
||||
QString _total_string;
|
||||
QString _received_string;
|
||||
|
||||
float _total = total;
|
||||
float _received = received;
|
||||
|
||||
if (_total < 1024)
|
||||
_total_string = tr ("%1 bytes").arg (_total);
|
||||
|
||||
else if (_total < 1024 * 1024) {
|
||||
_total = roundNumber (_total / 1024);
|
||||
_total_string = tr ("%1 KB").arg (_total);
|
||||
}
|
||||
|
||||
else {
|
||||
_total = roundNumber (_total / (1024 * 1024));
|
||||
_total_string = tr ("%1 MB").arg (_total);
|
||||
}
|
||||
|
||||
if (_received < 1024)
|
||||
_received_string = tr ("%1 bytes").arg (_received);
|
||||
|
||||
else if (received < 1024 * 1024) {
|
||||
_received = roundNumber (_received / 1024);
|
||||
_received_string = tr ("%1 KB").arg (_received);
|
||||
}
|
||||
|
||||
else {
|
||||
_received = roundNumber (_received / (1024 * 1024));
|
||||
_received_string = tr ("%1 MB").arg (_received);
|
||||
}
|
||||
|
||||
ui->downloadLabel->setText (tr ("Downloading updates") + " (" + _received_string + " " + tr ("of") + " " + _total_string + ")");
|
||||
|
||||
uint _diff = QDateTime::currentDateTime().toTime_t() - m_start_time;
|
||||
|
||||
if (_diff > 0) {
|
||||
QString _time_string;
|
||||
float _time_remaining = total / (received / _diff);
|
||||
|
||||
if (_time_remaining > 7200) {
|
||||
_time_remaining /= 3600;
|
||||
_time_string = tr ("About %1 hours").arg (int (_time_remaining + 0.5));
|
||||
}
|
||||
|
||||
else if (_time_remaining > 60) {
|
||||
_time_remaining /= 60;
|
||||
_time_string = tr ("About %1 minutes").arg (int (_time_remaining + 0.5));
|
||||
}
|
||||
|
||||
else if (_time_remaining <= 60)
|
||||
_time_string = tr ("%1 seconds").arg (int (_time_remaining + 0.5));
|
||||
|
||||
ui->timeLabel->setText (tr ("Time remaining") + ": " + _time_string);
|
||||
}
|
||||
}
|
||||
|
||||
// We do not know the size of the download, so we avoid scaring the shit out
|
||||
// of the user
|
||||
else {
|
||||
ui->progressBar->setValue (-1);
|
||||
ui->progressBar->setMinimum (0);
|
||||
ui->progressBar->setMaximum (0);
|
||||
ui->downloadLabel->setText (tr ("Downloading updates"));
|
||||
ui->timeLabel->setText (tr ("Time remaining") + ": " + tr ("Unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadDialog::ignoreSslErrors (QNetworkReply *reply,
|
||||
const QList<QSslError>& error) {
|
||||
#ifndef Q_OS_IOS
|
||||
reply->ignoreSslErrors (error);
|
||||
#else
|
||||
Q_UNUSED (reply);
|
||||
Q_UNUSED (error);
|
||||
#endif
|
||||
}
|
||||
|
||||
float DownloadDialog::roundNumber (const float& input) {
|
||||
return roundf (input * 100) / 100;
|
||||
}
|
||||
|
@ -1,64 +1,64 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DOWNLOAD_DIALOG_H
|
||||
#define DOWNLOAD_DIALOG_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QIcon>
|
||||
#include <QDateTime>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QDesktopServices>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace Ui {
|
||||
class DownloadDialog;
|
||||
}
|
||||
|
||||
class DownloadDialog : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadDialog (QWidget *parent = 0);
|
||||
~DownloadDialog (void);
|
||||
|
||||
void beginDownload (const QUrl& url);
|
||||
|
||||
private slots:
|
||||
void openDownload (void);
|
||||
void installUpdate (void);
|
||||
void cancelDownload (void);
|
||||
void downloadFinished (void);
|
||||
void updateProgress (qint64 received, qint64 total);
|
||||
void ignoreSslErrors (QNetworkReply *reply, const QList<QSslError>& error);
|
||||
|
||||
private:
|
||||
Ui::DownloadDialog *ui;
|
||||
|
||||
QString m_path;
|
||||
bool m_download_paused;
|
||||
|
||||
QNetworkReply *m_reply;
|
||||
QNetworkAccessManager *m_manager;
|
||||
|
||||
uint m_start_time;
|
||||
|
||||
float roundNumber (const float& input);
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DOWNLOAD_DIALOG_H
|
||||
#define DOWNLOAD_DIALOG_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QIcon>
|
||||
#include <QDateTime>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QDesktopServices>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace Ui {
|
||||
class DownloadDialog;
|
||||
}
|
||||
|
||||
class DownloadDialog : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadDialog (QWidget *parent = 0);
|
||||
~DownloadDialog (void);
|
||||
|
||||
void beginDownload (const QUrl& url);
|
||||
|
||||
private slots:
|
||||
void openDownload (void);
|
||||
void installUpdate (void);
|
||||
void cancelDownload (void);
|
||||
void downloadFinished (void);
|
||||
void updateProgress (qint64 received, qint64 total);
|
||||
void ignoreSslErrors (QNetworkReply *reply, const QList<QSslError>& error);
|
||||
|
||||
private:
|
||||
Ui::DownloadDialog *ui;
|
||||
|
||||
QString m_path;
|
||||
bool m_download_paused;
|
||||
|
||||
QNetworkReply *m_reply;
|
||||
QNetworkAccessManager *m_manager;
|
||||
|
||||
uint m_start_time;
|
||||
|
||||
float roundNumber (const float& input);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because one or more lines are too long
41
QSimpleUpdater/src/dialogs/progress_dialog.cpp
Normal file
41
QSimpleUpdater/src/dialogs/progress_dialog.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "progress_dialog.h"
|
||||
#include "ui_progress_dialog.h"
|
||||
|
||||
ProgressDialog::ProgressDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ProgressDialog)
|
||||
{
|
||||
// Create and configure UI
|
||||
ui->setupUi(this);
|
||||
|
||||
// Make the window look like a dialog
|
||||
QIcon _blank;
|
||||
setWindowIcon (_blank);
|
||||
setWindowModality (Qt::WindowModal);
|
||||
setWindowFlags (Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
|
||||
|
||||
// Close dialog when cancel button is clicked
|
||||
connect(ui->ui_cancel_button, SIGNAL(clicked()), this, SLOT(cancel()));
|
||||
}
|
||||
|
||||
ProgressDialog::~ProgressDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ProgressDialog::cancel(void) {
|
||||
hide();
|
||||
emit cancelClicked();
|
||||
}
|
42
QSimpleUpdater/src/dialogs/progress_dialog.h
Normal file
42
QSimpleUpdater/src/dialogs/progress_dialog.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef PROGRESS_DIALOG_H
|
||||
#define PROGRESS_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class ProgressDialog;
|
||||
}
|
||||
|
||||
class ProgressDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProgressDialog(QWidget *parent = 0);
|
||||
~ProgressDialog();
|
||||
|
||||
signals:
|
||||
void cancelClicked();
|
||||
|
||||
private slots:
|
||||
void cancel (void);
|
||||
|
||||
private:
|
||||
Ui::ProgressDialog *ui;
|
||||
};
|
||||
|
||||
#endif // PROGRESS_DIALOG_H
|
121
QSimpleUpdater/src/dialogs/progress_dialog.ui
Normal file
121
QSimpleUpdater/src/dialogs/progress_dialog.ui
Normal file
@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ProgressDialog</class>
|
||||
<widget class="QDialog" name="ProgressDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>410</width>
|
||||
<height>152</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Software Updater</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="ui_icon">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../res/qsu_resources.qrc">:/icons/update.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="ui_progress_bar">
|
||||
<property name="text">
|
||||
<string>Checking for updates...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="button_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<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="ui_cancel_button">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../res/qsu_resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,158 +1,480 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "qsimpleupdater.h"
|
||||
|
||||
QSimpleUpdater::QSimpleUpdater (QObject *parent)
|
||||
: QObject (parent)
|
||||
, m_changelog_downloaded (false)
|
||||
, m_version_check_finished (false)
|
||||
, m_new_version_available (false) {
|
||||
m_downloadDialog = new DownloadDialog();
|
||||
|
||||
m_manager = new QNetworkAccessManager (this);
|
||||
connect (m_manager, SIGNAL (finished (QNetworkReply *)), this,
|
||||
SLOT (checkDownloadedVersion (QNetworkReply *)));
|
||||
connect (m_manager, SIGNAL (sslErrors (QNetworkReply *, QList<QSslError>)),
|
||||
this, SLOT (ignoreSslErrors (QNetworkReply *, QList<QSslError>)));
|
||||
}
|
||||
|
||||
QString QSimpleUpdater::changeLog() const {
|
||||
return m_changelog;
|
||||
}
|
||||
|
||||
void QSimpleUpdater::checkForUpdates (void) {
|
||||
if (!m_reference_url.isEmpty())
|
||||
m_manager->get (QNetworkRequest (m_reference_url));
|
||||
|
||||
else
|
||||
qDebug() << "QSimpleUpdater: Invalid reference URL";
|
||||
}
|
||||
|
||||
void QSimpleUpdater::openDownloadLink (void) {
|
||||
if (!m_download_url.isEmpty())
|
||||
QDesktopServices::openUrl (m_download_url);
|
||||
}
|
||||
|
||||
QString QSimpleUpdater::latestVersion() const {
|
||||
return m_latest_version;
|
||||
}
|
||||
|
||||
QString QSimpleUpdater::installedVersion() const {
|
||||
return m_installed_version;
|
||||
}
|
||||
|
||||
void QSimpleUpdater::downloadLatestVersion (void) {
|
||||
if (!m_download_url.isEmpty())
|
||||
m_downloadDialog->beginDownload (m_download_url);
|
||||
}
|
||||
|
||||
bool QSimpleUpdater::newerVersionAvailable() const {
|
||||
return m_new_version_available;
|
||||
}
|
||||
|
||||
void QSimpleUpdater::setDownloadUrl (const QString& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
m_download_url.setUrl (url);
|
||||
}
|
||||
|
||||
void QSimpleUpdater::setReferenceUrl (const QString& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
m_reference_url.setUrl (url);
|
||||
}
|
||||
|
||||
void QSimpleUpdater::setChangelogUrl (const QString& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
m_changelog_url.setUrl (url);
|
||||
}
|
||||
|
||||
void QSimpleUpdater::setApplicationVersion (const QString& version) {
|
||||
Q_ASSERT (!version.isEmpty());
|
||||
m_installed_version = version;
|
||||
}
|
||||
|
||||
void QSimpleUpdater::checkDownloadedVersion (QNetworkReply *reply) {
|
||||
bool _new_update = false;
|
||||
|
||||
QString _reply = QString::fromUtf8 (reply->readAll());
|
||||
_reply.replace (" ", "");
|
||||
_reply.replace ("\n", "");
|
||||
|
||||
if (!_reply.isEmpty() && _reply.contains (".")) {
|
||||
m_latest_version = _reply;
|
||||
|
||||
QStringList _download = m_latest_version.split (".");
|
||||
QStringList _installed = m_installed_version.split (".");
|
||||
|
||||
for (int i = 0; i <= _download.count() - 1; ++i) {
|
||||
if (_download.count() - 1 >= i && _installed.count() - 1 >= i) {
|
||||
if (_download.at (i) > _installed.at (i)) {
|
||||
_new_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (_installed.count() < _download.count()) {
|
||||
if (_installed.at (i - 1) == _download.at (i - 1))
|
||||
break;
|
||||
|
||||
else {
|
||||
_new_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_new_version_available = _new_update;
|
||||
emit versionCheckFinished();
|
||||
|
||||
if (!m_changelog_url.isEmpty() && newerVersionAvailable()) {
|
||||
QNetworkAccessManager *_manager = new QNetworkAccessManager (this);
|
||||
|
||||
connect (_manager, SIGNAL (finished (QNetworkReply *)), this,
|
||||
SLOT (processDownloadedChangelog (QNetworkReply *)));
|
||||
|
||||
connect (_manager, SIGNAL (sslErrors (QNetworkReply *, QList<QSslError>)),
|
||||
this, SLOT (ignoreSslErrors (QNetworkReply *, QList<QSslError>)));
|
||||
|
||||
_manager->get (QNetworkRequest (m_changelog_url));
|
||||
}
|
||||
|
||||
else
|
||||
emit checkingFinished();
|
||||
}
|
||||
|
||||
void QSimpleUpdater::processDownloadedChangelog (QNetworkReply *reply) {
|
||||
QString _reply = QString::fromUtf8 (reply->readAll());
|
||||
|
||||
if (!_reply.isEmpty()) {
|
||||
m_changelog = _reply;
|
||||
emit changelogDownloadFinished();
|
||||
}
|
||||
|
||||
emit checkingFinished();
|
||||
}
|
||||
|
||||
void QSimpleUpdater::ignoreSslErrors (QNetworkReply *reply,
|
||||
const QList<QSslError>& error) {
|
||||
#if SUPPORTS_SSL
|
||||
reply->ignoreSslErrors (error);
|
||||
#else
|
||||
Q_UNUSED (reply);
|
||||
Q_UNUSED (error);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
/*! \class QSimpleUpdater
|
||||
* \brief A simple auto-updater system for Qt
|
||||
*
|
||||
* QSimpleUpdater is an implementation of an auto-updating system to be used with Qt projects.
|
||||
* Aside from notifying you if there's a newer version, it allows you to download the change log in any
|
||||
* format (such as HTML or RTF) and download the updates directly from your application using a dialog.
|
||||
* QSimpleUpdater is free and open source LGPL software,
|
||||
* which means that you can use it for both open source and proprietary applications.
|
||||
*
|
||||
* \chapter Installation
|
||||
*
|
||||
* \list
|
||||
* \o Copy the QSimpleUpdater folder in your "3rd-party" folder.
|
||||
* \o Include the QSimpleUpdater project include (pri) file using the include() function.
|
||||
* \o That's all! Check the example project as a reference for your project.
|
||||
* \endlist
|
||||
*
|
||||
* \chapter Running the example project
|
||||
*
|
||||
* \list
|
||||
* \o Navigate to the Example folder and open example.pro with Qt Creator.
|
||||
* \o Compile the project and play with it :)
|
||||
* \endlist
|
||||
*
|
||||
* \chapter Warnings
|
||||
* Many websites today use the HTTP Secure protocol, which means that you will need SSL
|
||||
* in order to communicate with them.
|
||||
* If your project needs to access such a webiste (for example GitHub),
|
||||
* you will need to carefully read the following information in order to ensure that
|
||||
* QSimpleUpdater works with those websites (both in your machine and in the final users' machine).
|
||||
*
|
||||
* This section is extremely important for any developers wishing to deploy their applications under
|
||||
* the Windows platform, because the application will depend on the OpenSSL libaries in order to work.
|
||||
*
|
||||
* \bold {Linux}
|
||||
*
|
||||
* Make sure that you have installed the following libraries in your system:
|
||||
*
|
||||
* \list
|
||||
* \o lssl
|
||||
* \o lcrypto
|
||||
* \endlist
|
||||
*
|
||||
* \bold {Mac OS X}
|
||||
*
|
||||
* The libraries required by QSimpleUpdater are the same as Linux, however, these libraries
|
||||
* are installed by default in most Mac OS X installations.
|
||||
*
|
||||
* \bold {Microsoft Windows}
|
||||
*
|
||||
* QSimpleUpdater makes use of the OpenSSL-Win32 project, make sure that have it installed
|
||||
* and that the project knows where to find them (the default location is C:/OpenSSL-Win32).
|
||||
* Finally, deploy the following libraries with your compiled project:
|
||||
*
|
||||
* \list
|
||||
* \o libeay32.dll
|
||||
* \o ssleay32.dll
|
||||
* \endlist
|
||||
*/
|
||||
|
||||
/*! \fn QSimpleUpdater::checkingFinished (void)
|
||||
* This signal is triggered when the updater system finishes downloading
|
||||
* and proccessing the version data and changelog data.
|
||||
*/
|
||||
|
||||
#include "qsimpleupdater.h"
|
||||
|
||||
/*! \internal
|
||||
* Initializes and configures the class.
|
||||
*/
|
||||
|
||||
QSimpleUpdater::QSimpleUpdater (QObject *parent)
|
||||
: QObject (parent)
|
||||
, m_silent (false)
|
||||
, m_show_newest_version (true)
|
||||
, m_show_update_available (true)
|
||||
, m_new_version_available (false) {
|
||||
|
||||
m_progressDialog = new ProgressDialog();
|
||||
m_downloadDialog = new DownloadDialog();
|
||||
|
||||
m_manager = new QNetworkAccessManager (this);
|
||||
connect (m_manager, SIGNAL (finished (QNetworkReply *)), this,
|
||||
SLOT (checkDownloadedVersion (QNetworkReply *)));
|
||||
connect (m_manager, SIGNAL (sslErrors (QNetworkReply *, QList<QSslError>)),
|
||||
this, SLOT (ignoreSslErrors (QNetworkReply *, QList<QSslError>)));
|
||||
|
||||
connect (m_progressDialog, SIGNAL(cancelClicked()), this, SLOT(cancel()));
|
||||
connect (this, SIGNAL (checkingFinished()), this, SLOT (onCheckingFinished()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the downloaded change log as a \c QString.
|
||||
*
|
||||
* \sa setChangelogUrl()
|
||||
*/
|
||||
|
||||
QString QSimpleUpdater::changeLog() const {
|
||||
return m_changelog;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Checks for updates and calls the appropiate functions
|
||||
* when finished.
|
||||
*
|
||||
* \sa setDownloadUrl(), setReferenceUrl()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::checkForUpdates (void) {
|
||||
if (!m_reference_url.isEmpty()) {
|
||||
m_manager->get (QNetworkRequest (m_reference_url));
|
||||
|
||||
if (!silent())
|
||||
m_progressDialog->show();
|
||||
}
|
||||
|
||||
else
|
||||
qDebug() << "QSimpleUpdater: Invalid reference URL";
|
||||
}
|
||||
|
||||
/*!
|
||||
* Opens the download link in a web browser.
|
||||
*
|
||||
* \sa setDownloadUrl()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::openDownloadLink (void) {
|
||||
if (!m_download_url.isEmpty())
|
||||
QDesktopServices::openUrl (m_download_url);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the latest version as a \c QString.
|
||||
*
|
||||
* \sa setReferenceUrl(), checkForUpdates()
|
||||
*/
|
||||
|
||||
QString QSimpleUpdater::latestVersion() const {
|
||||
return m_latest_version;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the local version of the application.
|
||||
*
|
||||
* \sa setApplicationVersion()
|
||||
*/
|
||||
|
||||
QString QSimpleUpdater::installedVersion() const {
|
||||
return m_installed_version;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Downloads the latest version of the application
|
||||
* and displays download info in a dialog.
|
||||
*
|
||||
* \sa setDownloadUrl(), checkForUpdates()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::downloadLatestVersion (void) {
|
||||
if (!m_download_url.isEmpty())
|
||||
m_downloadDialog->beginDownload (m_download_url);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns \c true if the system detected that there is
|
||||
* a newer version of the application available online.
|
||||
*
|
||||
* \sa setReferenceUrl(), checkForUpdates()
|
||||
*/
|
||||
|
||||
bool QSimpleUpdater::newerVersionAvailable() const {
|
||||
return m_new_version_available;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns \c true if the system is set to
|
||||
* hide the progress dialog.
|
||||
*
|
||||
* \sa setSilent()
|
||||
*/
|
||||
|
||||
bool QSimpleUpdater::silent() const {
|
||||
return m_silent;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Tells the system from where to download the update packages
|
||||
* with the \a url parameter.
|
||||
*
|
||||
* Its recommended to use fixed URLs if you
|
||||
* want to automatically download and install your updates using
|
||||
* the bundled download dialog.
|
||||
*
|
||||
* \sa downloadLatestVersion(), openDownloadLink()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::setDownloadUrl (const QString& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
m_download_url.setUrl (url);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Tells the updater system from where to download the file
|
||||
* that indicates the latest version using the \a url parameter.
|
||||
*
|
||||
* The reference file should contain \bold {ONLY} the latest version
|
||||
* in a plain text format. For example:
|
||||
*
|
||||
* \list
|
||||
* \o 1
|
||||
* \o 0.1
|
||||
* \o 1.0.1
|
||||
* \o 2.2.12
|
||||
* \o etc
|
||||
* \endlist
|
||||
*
|
||||
* \sa latestVersion()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::setReferenceUrl (const QString& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
m_reference_url.setUrl (url);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Tells the updater system from where to download the
|
||||
* change log using the \a url parameter.
|
||||
* The change log can be any file you like, however,
|
||||
* its recommended to write it in plain text,
|
||||
* such as TXT, HTML and RTF files.
|
||||
*
|
||||
* \sa changeLog()
|
||||
*/
|
||||
|
||||
|
||||
void QSimpleUpdater::setChangelogUrl (const QString& url) {
|
||||
Q_ASSERT (!url.isEmpty());
|
||||
m_changelog_url.setUrl (url);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Tells the updater the version of the installed
|
||||
* copy of your application using the \a version parameter.
|
||||
*
|
||||
* Calling this function is optional, as the default
|
||||
* values are loaded from QApplication class.
|
||||
*
|
||||
* \sa installedVersion(), checkForUpdates()
|
||||
*/
|
||||
|
||||
|
||||
void QSimpleUpdater::setApplicationVersion (const QString& version) {
|
||||
Q_ASSERT (!version.isEmpty());
|
||||
m_installed_version = version;
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \list
|
||||
* \o If \a silent is set to \c true, no dialogs will be shown while checking
|
||||
* for updates or when a newer version of the application is found.
|
||||
* \o If \a silent is set to \c false, a dialog will be shown while checking for
|
||||
* updates or when a newer version of the application is found.
|
||||
* \endlist
|
||||
*
|
||||
* \sa silent()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::setSilent (bool silent) {
|
||||
m_silent = silent;
|
||||
|
||||
if (m_silent)
|
||||
setShowNewestVersionMessage(false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* If the \a show parameter is set to \c true, the updater system will show a
|
||||
* message box notifying the user when there's an update available.
|
||||
*
|
||||
* \sa checkForUpdates()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::setShowUpdateAvailableMessage(bool show) {
|
||||
m_show_update_available = show;
|
||||
}
|
||||
|
||||
/*!
|
||||
* If the \a show parameter is set to \c true, the updater system will show a
|
||||
* message box notifying the user when the latest version is already installed.
|
||||
*
|
||||
* For example, this configuration is useful when the user manually calls this function.
|
||||
* \i {Eg:} when he or she clicks the "Check for updates" menu item.
|
||||
*
|
||||
* \sa checkForUpdates()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::setShowNewestVersionMessage(bool show) {
|
||||
m_show_newest_version = show;
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
* Disconnects the network access manager when the user
|
||||
* clicks on the "cancel" button in the progress dialog.
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::cancel(void) {
|
||||
m_manager->disconnect();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
* Alerts the user when the download of version information
|
||||
* data is corrupted.
|
||||
*
|
||||
* \sa checkDownloadedVersion()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::showErrorMessage (void) {
|
||||
if (!silent())
|
||||
QMessageBox::warning(NULL, tr("Software Updater"),
|
||||
tr("An unknown error occured while checking for updates"));
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
* Informs the user if there's a newer version available for download
|
||||
* or if he or she is running the latest version of the application.
|
||||
*
|
||||
* \sa checkDownloadedVersion()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::onCheckingFinished (void) {
|
||||
// Get the application icon as a pixmap
|
||||
QPixmap _icon = qApp->windowIcon().pixmap(
|
||||
qApp->windowIcon().actualSize(QSize(96, 96)));
|
||||
|
||||
// If the icon is invalid, use default icon
|
||||
if (_icon.isNull())
|
||||
_icon = QPixmap(":/icons/update.png");
|
||||
|
||||
QMessageBox _message;
|
||||
_message.setIconPixmap (_icon);
|
||||
|
||||
// Ask user if he/she wants to download newer version
|
||||
if (newerVersionAvailable() && m_show_update_available) {
|
||||
_message.setDetailedText (changeLog());
|
||||
_message.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
|
||||
_message.setText ("<b>" + tr ("A new version of %1 is available!").arg(qApp->applicationName()) + "</b>");
|
||||
_message.setInformativeText (tr("%1 %2 is available - you have %3. Would you like to download it now?")
|
||||
.arg(qApp->applicationName())
|
||||
.arg(latestVersion())
|
||||
.arg(installedVersion()));
|
||||
|
||||
if (_message.exec() == QMessageBox::Yes)
|
||||
downloadLatestVersion();
|
||||
}
|
||||
|
||||
// Tell user that he/she is up to date (only if necessary)
|
||||
else if (!silent() && m_show_newest_version && !m_latest_version.isEmpty()) {
|
||||
_message.setStandardButtons (QMessageBox::Ok);
|
||||
_message.setText ("<b>" + tr ("You're up-to-date!") +
|
||||
" </b>");
|
||||
_message.setInformativeText (
|
||||
tr ("%1 %2 is currently the newest version available")
|
||||
.arg (qApp->applicationName())
|
||||
.arg (installedVersion()));
|
||||
|
||||
_message.exec();
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
* Compares downloaded version information with local version information
|
||||
* and decides if there's a newer version available.
|
||||
*
|
||||
* Finally, the function downloads the changelog if there's a newer version
|
||||
* available online.
|
||||
*
|
||||
* \sa checkForUpdates()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::checkDownloadedVersion (QNetworkReply *reply) {
|
||||
bool _new_update = false;
|
||||
m_progressDialog->hide();
|
||||
|
||||
QString _reply = QString::fromUtf8 (reply->readAll());
|
||||
_reply.replace (" ", "");
|
||||
_reply.replace ("\n", "");
|
||||
|
||||
if (!_reply.isEmpty()) {
|
||||
m_latest_version = _reply;
|
||||
|
||||
QStringList _download = m_latest_version.split (".");
|
||||
QStringList _installed = m_installed_version.split (".");
|
||||
|
||||
for (int i = 0; i <= _download.count() - 1; ++i) {
|
||||
if (_download.count() - 1 >= i && _installed.count() - 1 >= i) {
|
||||
if (_download.at (i) > _installed.at (i)) {
|
||||
_new_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (_installed.count() < _download.count()) {
|
||||
if (_installed.at (i - 1) == _download.at (i - 1))
|
||||
break;
|
||||
|
||||
else {
|
||||
_new_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_new_version_available = _new_update;
|
||||
|
||||
else
|
||||
showErrorMessage();
|
||||
|
||||
if (!m_changelog_url.isEmpty() && newerVersionAvailable()) {
|
||||
QNetworkAccessManager *_manager = new QNetworkAccessManager (this);
|
||||
|
||||
connect (_manager, SIGNAL (finished (QNetworkReply *)), this,
|
||||
SLOT (processDownloadedChangelog (QNetworkReply *)));
|
||||
|
||||
connect (_manager, SIGNAL (sslErrors (QNetworkReply *, QList<QSslError>)),
|
||||
this, SLOT (ignoreSslErrors (QNetworkReply *, QList<QSslError>)));
|
||||
|
||||
_manager->get (QNetworkRequest (m_changelog_url));
|
||||
}
|
||||
|
||||
else
|
||||
emit checkingFinished();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
* Reads the downloaded changelog data and transforms it into a QString.
|
||||
*
|
||||
* \sa setChangelogUrl(), changeLog()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::processDownloadedChangelog (QNetworkReply *reply) {
|
||||
QString _reply = QString::fromUtf8 (reply->readAll());
|
||||
|
||||
if (!_reply.isEmpty())
|
||||
m_changelog = _reply;
|
||||
|
||||
emit checkingFinished();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
* Allows the download process to continue even if there are SSL errors.
|
||||
*
|
||||
* \sa checkForUpdates()
|
||||
*/
|
||||
|
||||
void QSimpleUpdater::ignoreSslErrors (QNetworkReply *reply,
|
||||
const QList<QSslError>& error) {
|
||||
#if SUPPORTS_SSL
|
||||
reply->ignoreSslErrors (error);
|
||||
#else
|
||||
Q_UNUSED (reply);
|
||||
Q_UNUSED (error);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,120 +1,96 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef Q_SIMPLE_UPDATER_H
|
||||
#define Q_SIMPLE_UPDATER_H
|
||||
|
||||
#define SUPPORTS_SSL !defined(Q_OS_IOS)
|
||||
|
||||
#include <QUrl>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QDesktopServices>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#if SUPPORTS_SSL
|
||||
#include <QSsl>
|
||||
#include <QSslError>
|
||||
#include <QSslConfiguration>
|
||||
#endif
|
||||
|
||||
#include "dialogs/download_dialog.h"
|
||||
|
||||
class QSimpleUpdater : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QSimpleUpdater (QObject *parent = 0);
|
||||
|
||||
/// Returns the downloaded change log
|
||||
QString changeLog() const;
|
||||
|
||||
/// Returns the downloaded version string
|
||||
QString latestVersion() const;
|
||||
|
||||
/// Returns the local version, referenced by
|
||||
/// the setApplicationVersion() function
|
||||
QString installedVersion() const;
|
||||
|
||||
/// Returns \c true if there's a newer version available
|
||||
bool newerVersionAvailable() const;
|
||||
|
||||
/// Checks for updates and calls the appropriate
|
||||
/// signals when finished
|
||||
void checkForUpdates (void);
|
||||
|
||||
/// Opens the download URL in a a web browser.
|
||||
/// The URL is referenced by the \c setDownloadUrl() function
|
||||
void openDownloadLink (void);
|
||||
|
||||
/// Shows a dialog that downloads the file in the
|
||||
/// URL referenced by the \c setDownloadUrl() function
|
||||
void downloadLatestVersion (void);
|
||||
|
||||
public slots:
|
||||
|
||||
/// Changes the URL that we can open in a web browser or
|
||||
/// download. Its recommended to use fixed URLs if you
|
||||
/// want to automatically download and install your updates
|
||||
void setDownloadUrl (const QString& url);
|
||||
|
||||
/// Changes the reference URL, which contains ONLY the latest
|
||||
/// version of your application as a plain text file.
|
||||
/// Examples include:
|
||||
/// - 1.2.3
|
||||
/// - 5.4.0
|
||||
/// - 0.1.2
|
||||
/// - etc.
|
||||
void setReferenceUrl (const QString& url);
|
||||
|
||||
/// Changes the change log URL, which contains the change log
|
||||
/// of your application. The change log can be any file you
|
||||
/// like, however, its recommended to write it in plain text,
|
||||
/// such as TXT, HTML and RTF files.
|
||||
void setChangelogUrl (const QString& url);
|
||||
|
||||
/// Tells the updater the version of the installed
|
||||
/// copy of your application.
|
||||
void setApplicationVersion (const QString& version);
|
||||
|
||||
private slots:
|
||||
void checkDownloadedVersion (QNetworkReply *reply);
|
||||
void processDownloadedChangelog (QNetworkReply *reply);
|
||||
void ignoreSslErrors (QNetworkReply *reply, const QList<QSslError>& error);
|
||||
|
||||
signals:
|
||||
void checkingFinished (void);
|
||||
void versionCheckFinished (void);
|
||||
void changelogDownloadFinished (void);
|
||||
|
||||
private:
|
||||
QString m_changelog;
|
||||
QString m_latest_version;
|
||||
QString m_installed_version;
|
||||
QNetworkAccessManager *m_manager;
|
||||
|
||||
QUrl m_download_url;
|
||||
QUrl m_reference_url;
|
||||
QUrl m_changelog_url;
|
||||
|
||||
bool m_changelog_downloaded;
|
||||
bool m_version_check_finished;
|
||||
|
||||
bool m_new_version_available;
|
||||
|
||||
DownloadDialog *m_downloadDialog;
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
* (C) Copyright 2014 Alex Spataru
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Lesser General Public License
|
||||
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef Q_SIMPLE_UPDATER_H
|
||||
#define Q_SIMPLE_UPDATER_H
|
||||
|
||||
#define SUPPORTS_SSL !defined(Q_OS_IOS)
|
||||
|
||||
#include <QUrl>
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QDesktopServices>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#if SUPPORTS_SSL
|
||||
#include <QSsl>
|
||||
#include <QSslError>
|
||||
#include <QSslConfiguration>
|
||||
#endif
|
||||
|
||||
#include "dialogs/download_dialog.h"
|
||||
#include "dialogs/progress_dialog.h"
|
||||
|
||||
class QSimpleUpdater : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QSimpleUpdater (QObject *parent = 0);
|
||||
|
||||
QString changeLog() const;
|
||||
QString latestVersion() const;
|
||||
QString installedVersion() const;
|
||||
|
||||
bool silent() const;
|
||||
bool newerVersionAvailable() const;
|
||||
|
||||
void checkForUpdates (void);
|
||||
void openDownloadLink (void);
|
||||
void downloadLatestVersion (void);
|
||||
|
||||
public slots:
|
||||
void setSilent (bool silent);
|
||||
void setDownloadUrl (const QString& url);
|
||||
void setReferenceUrl (const QString& url);
|
||||
void setChangelogUrl (const QString& url);
|
||||
void setShowNewestVersionMessage(bool show);
|
||||
void setShowUpdateAvailableMessage(bool show);
|
||||
void setApplicationVersion (const QString& version);
|
||||
|
||||
signals:
|
||||
void checkingFinished (void);
|
||||
|
||||
private slots:
|
||||
void cancel (void);
|
||||
void showErrorMessage (void);
|
||||
void onCheckingFinished (void);
|
||||
void checkDownloadedVersion (QNetworkReply *reply);
|
||||
void processDownloadedChangelog (QNetworkReply *reply);
|
||||
void ignoreSslErrors (QNetworkReply *reply, const QList<QSslError>& error);
|
||||
|
||||
private:
|
||||
QString m_changelog;
|
||||
QString m_latest_version;
|
||||
QString m_installed_version;
|
||||
QNetworkAccessManager *m_manager;
|
||||
|
||||
QUrl m_download_url;
|
||||
QUrl m_reference_url;
|
||||
QUrl m_changelog_url;
|
||||
|
||||
bool m_silent;
|
||||
bool m_show_newest_version;
|
||||
bool m_show_update_available;
|
||||
bool m_new_version_available;
|
||||
|
||||
DownloadDialog *m_downloadDialog;
|
||||
ProgressDialog *m_progressDialog;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
108
Readme.md
108
Readme.md
@ -1,55 +1,55 @@
|
||||
## QSimpleUpdater
|
||||
|
||||
[![OpenHub](https://www.openhub.net/p/qsimpleupdater/widgets/project_thin_badge.gif)](http://openhub.net/p/qsimpleupdater)
|
||||
|
||||
QSimpleUpdater is an implementation of an auto-updating system to be used with Qt projects.
|
||||
|
||||
QSimpleUpdater is **free and open source [LGPL software](https://www.gnu.org/licenses/lgpl.html)**, which means that you can use it for both open source and proprietary applications.
|
||||
|
||||
## Using QSimpleUpdater
|
||||
|
||||
1. Copy the *QSimpleUpdater* folder in your "3rd-party" folder.
|
||||
2. Include the QSimpleUpdater project include (pri) file using the include() function.
|
||||
3. That's all! Check the example project as a reference for your project.
|
||||
|
||||
## Running the example project
|
||||
|
||||
1. Navigate to the *Example* folder and open *example.pro* with [Qt Creator](http://qt-project.org/wiki/Category:Tools::QtCreator).
|
||||
2. Compile the project and play with it *:)*
|
||||
|
||||
## Warnings
|
||||
|
||||
Many websites today use the HTTPS protocol, which means that you will need SSL in order to communicate with them. If your project needs to access such a webiste (for example GitHub), you will need to carefully read the following information in order to ensure that QSimpleUpdater works with those websites (both in your machine and in the final users' machine).
|
||||
|
||||
This section is extremely important for any developer wishing to deploy his or her applications under the Windows platform, because the application will depend on the libraries provided by QSimpleUpdater.
|
||||
|
||||
### Linux
|
||||
|
||||
Make sure that you have installed the following libraries in your system:
|
||||
|
||||
+ lssl
|
||||
+ lcrypto
|
||||
|
||||
### Mac OS X
|
||||
|
||||
The libraries required by QSimpleUpdater are the same as Linux, however, these libraries are installed by default in most Mac OS X installations.
|
||||
|
||||
### Windows
|
||||
|
||||
QSimpleUpdater makes use of the OpenSSL-Win32 project, make sure that have it installed and that the project knows where to find them (the default location is C:/OpenSSL-Win32) and that you deploy the following libraries with your compiled project:
|
||||
|
||||
+ libeay32.dll
|
||||
+ ssleay32.dll
|
||||
|
||||
## Donate
|
||||
|
||||
Donate [Bitcoins](http://bitcoin.org) to the project to keep it going!
|
||||
|
||||
> 1FFz9TZCPGgiCD97yEqnFaauYYvZUE7f51
|
||||
|
||||
## Useful Links
|
||||
|
||||
+ [Project website](http://qsimpleupdater.sourceforge.net)
|
||||
+ [OpenHub Project](http://openhub.net/p/qsimpleupdater)
|
||||
+ [GitHub repository](http://github.com/alex-97/qsimpleupdater)
|
||||
## QSimpleUpdater
|
||||
|
||||
[![OpenHub](https://www.openhub.net/p/qsimpleupdater/widgets/project_thin_badge.gif)](http://openhub.net/p/qsimpleupdater)
|
||||
|
||||
QSimpleUpdater is an implementation of an auto-updating system to be used with Qt projects.
|
||||
|
||||
QSimpleUpdater is **free and open source [LGPL software](https://www.gnu.org/licenses/lgpl.html)**, which means that you can use it for both open source and proprietary applications.
|
||||
|
||||
## Using QSimpleUpdater
|
||||
|
||||
1. Copy the *QSimpleUpdater* folder in your "3rd-party" folder.
|
||||
2. Include the QSimpleUpdater project include (pri) file using the include() function.
|
||||
3. That's all! Check the example project as a reference for your project.
|
||||
|
||||
## Running the example project
|
||||
|
||||
1. Navigate to the *Example* folder and open *example.pro* with [Qt Creator](http://qt-project.org/wiki/Category:Tools::QtCreator).
|
||||
2. Compile the project and play with it *:)*
|
||||
|
||||
## Warnings
|
||||
|
||||
Many websites today use the [HTTP Secure](http://en.wikipedia.org/wiki/HTTP_Secure) protocol, which means that you will need [SSL](https://www.globalsign.com/en/ssl-information-center/what-ssl/) in order to communicate with them. If your project needs to access such a webiste (for example GitHub), you will need to carefully read the following information in order to ensure that QSimpleUpdater works with those websites (both in your machine and in the final users' machine).
|
||||
|
||||
This section is extremely important for any developer wishing to deploy his or her applications under the Windows platform, because the application will depend on the libraries provided by QSimpleUpdater.
|
||||
|
||||
### Linux
|
||||
|
||||
Make sure that you have installed the following libraries in your system:
|
||||
|
||||
+ lssl
|
||||
+ lcrypto
|
||||
|
||||
### Mac OS X
|
||||
|
||||
The libraries required by QSimpleUpdater are the same as Linux, however, these libraries are installed by default in most Mac OS X installations.
|
||||
|
||||
### Windows
|
||||
|
||||
QSimpleUpdater makes use of the OpenSSL-Win32 project, make sure that have it installed and that the project knows where to find them (the default location is C:/OpenSSL-Win32) and that you deploy the following libraries with your compiled project:
|
||||
|
||||
+ libeay32.dll
|
||||
+ ssleay32.dll
|
||||
|
||||
## Donate
|
||||
|
||||
Donate [Bitcoins](http://bitcoin.org) to the project to keep it going!
|
||||
|
||||
> 1FFz9TZCPGgiCD97yEqnFaauYYvZUE7f51
|
||||
|
||||
## Useful Links
|
||||
|
||||
+ [Project website](http://qsimpleupdater.sourceforge.net)
|
||||
+ [OpenHub Project](http://openhub.net/p/qsimpleupdater)
|
||||
+ [GitHub repository](http://github.com/alex-97/qsimpleupdater)
|
||||
+ [Contact developer](mailto:alex.racotta@gmail.com)
|
Loading…
x
Reference in New Issue
Block a user