First commit

This commit is contained in:
Alex Spataru 2014-11-02 19:36:41 -06:00
parent 9d044e370f
commit 5180987ec1
12 changed files with 988 additions and 3 deletions

4
Authors.txt Executable file
View File

@ -0,0 +1,4 @@
QSIMPLEUPDATER AUTHORS
----------------------
Alex Spataru <alex_spataru@outlook.com>

96
Example/example.cpp Normal file
View File

@ -0,0 +1,96 @@
#include "example.h"
#include "ui_example.h"
int main (int argc, char *argv[]) {
QApplication app(argc, argv);
// Create the dialog and show it
Example example;
example.show();
// Run the app
return app.exec();
}
Example::Example (QWidget *parent) : QDialog(parent), ui(new Ui::Example) {
// Create and configure the user interface
ui->setupUi(this);
// Close the dialog when the close button is clicked
connect (ui->closeButton, SIGNAL(clicked()), this, SLOT(close()));
// Check for updates when the updates button is clicked
connect (ui->updatesButton, SIGNAL(clicked()), this, SLOT(checkForUpdates()));
// Initialize the updater
updater = new QSimpleUpdater(this);
// When the updater finishes checking for updates, show a message box
// and show the change log of the latest version
connect (updater, SIGNAL(checkingFinished()), this, SLOT(onCheckingFinished()));
}
Example::~Example() {
delete ui;
}
void Example::checkForUpdates() {
// Disable the check for updates button while the updater
// is checking for updates
ui->updatesButton->setEnabled(false);
ui->updatesButton->setText("Checking for updates...");
// If the user changed the text of the versionLineEdit, then change the
// application version in the updater too
if (!ui->versionLineEdit->text().isEmpty()) {
updater->setApplicationVersion(ui->versionLineEdit->text());
}
// If the versionLineEdit is empty, then set the application version
// to "0.1"
else {
updater->setApplicationVersion("0.1");
}
// Tell the updater where we should download the changelog, note that
// the changelog can be any file you want,
// such as an HTML page or (as in this example), a text file
updater->setChangelogUrl("https://raw.githubusercontent.com/alex-97/"
"QSimpleUpdater/Files-for-example-project/changelog.txt");
// Tell the updater where we can find the file that tells us the latest version
// of the application
updater->setReferenceUrl("https://raw.githubusercontent.com/alex-97/"
"QSimpleUpdater/Files-for-example-project/current_version.txt");
// Finally, check for updates...
updater->checkForUpdates();
}
void Example::onCheckingFinished() {
// Enable the updatesButton and change its text to let the user know
// 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());
QMessageBox::information(this, tr("Update available"),
tr("There's a newer version available! The latest version is ") +
updater->latestVersion());
}
// 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->setPlaceholderText("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!"));
}
}

31
Example/example.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef EXAMPLE_H
#define EXAMPLE_H
#include <QDialog>
#include <QMessageBox>
#include <QSimpleUpdater>
namespace Ui {
class Example;
}
class Example : public QDialog
{
Q_OBJECT
public:
explicit Example(QWidget *parent = 0);
~Example();
public slots:
void checkForUpdates();
void onCheckingFinished();
private:
Ui::Example *ui;
QString m_installed_version;
QSimpleUpdater *updater;
};
#endif

10
Example/example.pro Executable file
View File

@ -0,0 +1,10 @@
# Include the QSimpleUpdater files
include($$PWD/../QSimpleUpdater/qsimpleupdater.pri)
# Include the QtWidgets module
QT += widgets
# Define the source code
FORMS += example.ui
HEADERS += example.h
SOURCES += example.cpp

272
Example/example.pro.user Normal file
View File

@ -0,0 +1,272 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.2.1, 2014-11-02T19:34:42. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{138987cd-8d79-4dd6-8bdf-352f0efeeac3}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="ClangProjectSettings">
<value type="QString" key="CustomPchFile"></value>
<value type="int" key="PchUsage">1</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.3.2 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.3.2 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{919246e3-cae5-44ff-ad50-bfa69059c261}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/Alex/Documents/Developer/Projects/qupdater/build-example-Desktop_Qt_5_3_2_GCC_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/Alex/Documents/Developer/Projects/qupdater/build-example-Desktop_Qt_5_3_2_GCC_64bit-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">example</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/Users/Alex/Documents/Developer/Projects/qupdater/Example/example.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">example.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">16</value>
</data>
<data>
<variable>Version</variable>
<value type="int">16</value>
</data>
</qtcreator>

90
Example/example.ui Normal file
View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Example</class>
<widget class="QDialog" name="Example">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>QSimpleUpdater Example</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="versionLabel">
<property name="text">
<string>Set installed version (latest version is 1.0)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="versionLineEdit">
<property name="placeholderText">
<string>0.1 (default)</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="changelogLabel">
<property name="text">
<string>Changelog of latest version</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="changelogTextEdit">
<property name="font">
<font>
<family>Courier</family>
<pointsize>11</pointsize>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="backgroundVisible">
<bool>false</bool>
</property>
<property name="placeholderText">
<string>Click on the &quot;Check for Updates&quot; button to download the changelog of the latest version</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="updatesButton">
<property name="text">
<string>Check for updates</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

5
LICENSE → License.txt Normal file → Executable file
View File

@ -1,4 +1,4 @@
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
@ -162,5 +162,4 @@ General Public License ever published by the Free Software Foundation.
whether future versions of the GNU Lesser General Public License shall whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the permanent authorization for you to choose that version for the
Library. Library.

View File

@ -0,0 +1,24 @@
#
# This file is part of QSimpleUpdater
#
# Copyright (c) 2014 Alex Spataru <alex_spataru@outlook.com>
#
# Please check the license.txt file for more information.
#
QT += network
HEADERS += $$PWD/src/qsimpleupdater.h
SOURCES += $$PWD/src/qsimpleupdater.cpp
OTHER_FILES += $$PWD/src/QSimpleUpdater
INCLUDEPATH += $$PWD/src
macx || linux{
LIBS += -lcrypto -lssl
}
win32* {
CONFIG += openssl-linked
LIBS += -L$$PWD/dependencies/win32/ -llibeay32
}

View File

@ -0,0 +1 @@
#include "qsimpleupdater.h"

View File

@ -0,0 +1,260 @@
//
// This file is part of QSimpleUpdater
//
// Copyright (c) 2014 Alex Spataru <alex_spataru@gmail.com>
//
// Please check the license.txt file for more information.
//
#include "qsimpleupdater.h"
QSimpleUpdater::QSimpleUpdater(QObject *parent) : QObject(parent) {}
QString QSimpleUpdater::changeLog() {
// Return the contents of the downloaded changelog
if (!m_changelog.isEmpty()) {
return m_changelog;
}
// If the changelog is empty, we issue a warning message in
// the console and return an empty string
else {
qWarning() << "QSimpleUpdater: change log is empty,"
<< "did you call setChangelogUrl() and checkForUpdates()?";
return NULL;
}
}
void QSimpleUpdater::checkForUpdates() {
// Only check for updates if we know which file should we download
if (!m_reference_url.isEmpty()) {
// Create a new network access manager, which allows us to
// download our desired file
QNetworkAccessManager *_manager = new QNetworkAccessManager(this);
// Compare the downloaded application version with the installed
// version when the download is finished
connect(_manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(checkDownloadedVersion(QNetworkReply*)));
// Ignore any possible SSL errors
connect(_manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
this, SLOT(ignoreSslErrors(QNetworkReply*,QList<QSslError>)));
// Finally, download the file
_manager->get (QNetworkRequest (m_reference_url));
}
// Issue a warning message in the case that the reference URL is empty...
else {
qWarning() << "QSimpleUpdater: Invalid reference URL";
}
}
QString QSimpleUpdater::latestVersion() {
// Return the application version referenced by the string
// that we downloaded
if (!m_latest_version.isEmpty()) {
return m_latest_version;
}
// Issue a warning message in the case that the downloaded
// application version string is empty
else {
qWarning() << "QSimpleUpdater: latest version is empty,"
<< "did you call checkForUpdates() and setReferenceUrl()?";
return NULL;
}
}
QString QSimpleUpdater::installedVersion() {
// Return the string issued by the user in the setApplicationVersion() function
if (!m_installed_version.isEmpty()) {
return m_installed_version;
}
// Issue a warning message in the case that the installed application
// version is empty
else {
qWarning() << "QSimpleUpdater: installed version is empty,"
<< "did you call setApplicationVersion()?";
return NULL;
}
}
void QSimpleUpdater::downloadLatestVersion() {
// Open the download URL in a web browser
if (!m_download_url.isEmpty()) {
QDesktopServices::openUrl(m_download_url);
}
// The m_download_url is empty, so we issue another warning message
else {
qWarning() << "QSimpleUpdater: cannot download latest version,"
<< "did you call setDownloadUrl() and checkForUpdates()?";
}
}
bool QSimpleUpdater::newerVersionAvailable() {
return m_new_version_available;
}
void QSimpleUpdater::setDownloadUrl(const QString url) {
// Change the download URL if the issued URL is valid
if (!url.isEmpty()) {
m_download_url.setUrl(url);
}
// The issued URL is ilegal, so we warn the user
else {
qWarning() << "QSimpleUpdater: input URL cannot be empty!";
}
}
void QSimpleUpdater::setReferenceUrl(const QString url) {
// Change the reference URL if the issued URL is valid
if (!url.isEmpty()) {
m_reference_url.setUrl(url);
}
// The issued URL is ilegal, so we warn the user
else {
qWarning() << "QSimpleUpdater: input URL cannot be empty!";
}
}
void QSimpleUpdater::setChangelogUrl(const QString url) {
// Change the changelog URL if the issued URL is valid
if (!url.isEmpty()) {
m_changelog_url.setUrl(url);
}
// The issued URL is ilegal, so we warn the user
else {
qWarning() << "QSimpleUpdater: input URL cannot be empty!";
}
}
void QSimpleUpdater::setApplicationVersion(const QString version) {
// Change the installed application version if the issued string is valid
if (!version.isEmpty()) {
m_installed_version = version;
}
// The application version cannot be empty, so we warn the user
else {
qWarning() << "QSimpleUpdater: input string cannot be empty!";
}
}
void QSimpleUpdater::checkDownloadedVersion(QNetworkReply *reply) {
bool _new_update = false;
// Read the reply from the server and transform it
// to a QString
QString _reply = QString::fromUtf8 (reply->readAll());
// If the reply from the server is not empty, compare
// the downloaded version with the installed version
if (!_reply.isEmpty()) {
// Replace the latest version string with the downloaded string
m_latest_version = _reply;
// Separate the downloaded and installed version
// string by their dots.
//
// For example, 0.9.1 would become:
// 1: 0
// 2: 9
// 3: 1
//
QStringList _download = m_latest_version.split (".");
QStringList _installed = m_installed_version.split (".");
// Compare the major, minor, build, etc. numbers
for (int i = 0; i <= _download.count() - 1; ++i) {
// Make sure that the number that we are goind to compare
// exists in both strings, for example, we will not compare
// 1.2.3 and 1.2.3.1 because we would crash the program
if (_download.count() >= i && _installed.count() >= i) {
// The downloaded number is greater than the installed number
// in question. So there's a newer version of the application
// available.
if (_download.at (i) > _installed.at (i)) {
_new_update = true;
break;
}
}
// If the number of dots are different, we can tell if
// there's a newer version by comparing the count of each
// version. For example, 1.2.3 is smaller than 1.2.3.1...
// Also, we will only reach this code when we finish comparing
// the "3" in both the downloaded and the installed version.
else {
if (_installed.count() > _download.count()) {
_new_update = true;
break;
}
}
}
}
// Update the value of the m_new_version_avialable boolean
m_new_version_available = _new_update;
// Notify our parent that we have finished downloading and comparing
// the application version
emit versionCheckFinished();
// If the changelog URL is valid, download the change log ONLY if
// there's a newer version available.
// Note that the processDownloadedChangeLog() function will
// notify our parent that we have finished checking for updates.
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));
}
// We did not download the changelog, so we notify our parent
// that we have finished checking for updates
else {
emit checkingFinished();
}
}
void QSimpleUpdater::processDownloadedChangelog(QNetworkReply *reply) {
// Read the downloaded file and transform it to a QString
QString _reply = QString::fromUtf8(reply->readAll());
// Change the changelog string and notify our
// parent that the changelog was downlaoded
if (!_reply.isEmpty()) {
m_changelog = _reply;
emit changelogDownloadFinished();
}
// Issue a warning in the case that the changelog is empty
else {
qWarning() << "QSimpleUpdater: downloaded change log is empty!";
}
// Tell our parent that we are done checking for updates
emit checkingFinished();
}
void QSimpleUpdater::ignoreSslErrors (QNetworkReply *reply, QList<QSslError> error) {
reply->ignoreSslErrors (error);
}

View File

@ -0,0 +1,60 @@
#ifndef Q_SIMPLE_UPDATER_H
#define Q_SIMPLE_UPDATER_H
#include <QSsl>
#include <QUrl>
#include <QString>
#include <QSslError>
#include <QByteArray>
#include <QStringList>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QDesktopServices>
#include <QSslConfiguration>
#include <QNetworkAccessManager>
class QSimpleUpdater : public QObject {
Q_OBJECT
public:
QSimpleUpdater(QObject *parent = 0);
QString changeLog();
void checkForUpdates();
QString latestVersion();
QString installedVersion();
void downloadLatestVersion();
bool newerVersionAvailable();
public slots:
void setDownloadUrl(const QString url);
void setReferenceUrl(const QString url);
void setChangelogUrl(const QString url);
void setApplicationVersion(const QString version);
private slots:
void checkDownloadedVersion(QNetworkReply *reply);
void processDownloadedChangelog(QNetworkReply *reply);
void ignoreSslErrors(QNetworkReply *reply, QList<QSslError> error);
signals:
void checkingFinished();
void versionCheckFinished();
void changelogDownloadFinished();
private:
QString m_changelog;
QString m_latest_version;
QString m_installed_version;
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;
};
#endif

138
Readme.md Executable file
View File

@ -0,0 +1,138 @@
## 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 propietary applications.
## Using QSimpleUpdater
#### 1. Import QSimpleUpdater to your project
1. Copy the <code>QSimpleUpdater</code> folder in your "3rd-party" folder.
3. Include the QSimpleUpdater project include (pri) file using the include() function.
5. That's all! Check the example project as a reference.
#### 2. Include QSimpleUpdater in your header file(s):
<div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #557799">#include &lt;QSimpleUpdater&gt;</span></pre></div>
#### 3. Declare a new instance of QSimpleUpdater in your header file (preferably as a private object).
<div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #557799">QSimpleUpdater *updater;</span></pre></div>
#### 4. Initialize and configure the updater when your class is created:
<div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"> MyClass<span style="color: #333333">::</span>MyClass() {
<span style="color: #888888">// Initialize the updater</span>
updater <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">new</span> QSimpleUpdater(<span style="color: #008800; font-weight: bold">this</span>);
<span style="color: #888888">// Define our application version....</span>
<span style="color: #888888">// The string must contain the same number</span>
<span style="color: #888888">// of dots as the one that we will download</span>
QString app_version <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&quot;1.2.3&quot;</span>
<span style="color: #888888">// This string will help us to specify which file</span>
<span style="color: #888888">// should we download when a new version of the app</span>
<span style="color: #888888">// is detected.</span>
QString download_url;
<span style="color: #888888">// The following code will help us to define from where</span>
<span style="color: #888888">// we should download the binary installation file </span>
<span style="color: #888888">// in the case that the updater detects a newer version</span>
<span style="color: #888888">// of your app.</span>
<span style="color: #888888">// Download the DMG file of your app </span>
<span style="color: #FF0000; background-color: #FFAAAA">#</span>ifdef Q_OS_MAC
download_url <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&quot;http://myapp.com/downloads/latest.dmg&quot;</span>;
<span style="color: #FF0000; background-color: #FFAAAA">#</span>endif
<span style="color: #888888">// Download the EXE setup for your app</span>
<span style="color: #FF0000; background-color: #FFAAAA">#</span>ifdef Q_OS_WIN
download_url <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&quot;http://myapp.com/downloads/latest.exe&quot;</span>;
<span style="color: #FF0000; background-color: #FFAAAA">#</span>endif
<span style="color: #888888">// Download a *.tar.gz file for your app</span>
<span style="color: #FF0000; background-color: #FFAAAA">#</span>ifdef Q_OS_LINUX
download_url <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&quot;http://myapp.com/downloads/latest.tar.gz&quot;</span>;
<span style="color: #FF0000; background-color: #FFAAAA">#</span>endif
<span style="color: #888888">// Version of the installed application (in this case, 1.2.3)</span>
<span style="color: #888888">// The parameter must be a QString.... </span>
updater<span style="color: #333333">-&gt;</span>setApplicationVersion(app_version);
<span style="color: #888888">// Tell the updater from where we should download</span>
<span style="color: #888888">// the installer of our application</span>
updater<span style="color: #333333">-&gt;</span>setDownloadUrl(QUrl(download_url));
<span style="color: #888888">// The following text file should only contain the </span>
<span style="color: #888888">// latest application version, for example, 1.2.3 or 1.2.4</span>
updater<span style="color: #333333">-&gt;</span>setReferenceUrl(QUrl(<span style="background-color: #fff0f0">&quot;http://myapp.com/latest.txt&quot;</span>));
<span style="color: #888888">// Tell the updater where to download the changelog...</span>
updater<span style="color: #333333">-&gt;</span>setChangelogUrl(QUrl(<span style="background-color: #fff0f0">&quot;http://myapp.com/changelog.txt&quot;</span>));
<span style="color: #888888">// Check for updates....</span>
updater<span style="color: #333333">-&gt;</span>checkForUpdates();
<span style="color: #888888">// Finally, do something when the updater finds a new version</span>
<span style="color: #888888">// of your app.</span>
connect(updater, SIGNAL(updateAvailable()),
<span style="color: #008800; font-weight: bold">this</span>, SLOT(onUpdateAvailable()));
}
</pre></div>
#### 5. Define what your application should do when the updater finds a new version of your application. For example:
<div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">MyClass<span style="color: #333333">::</span>onUpdateAvailable() {
qDebug() <span style="color: #333333">&lt;&lt;</span> <span style="background-color: #fff0f0">&quot;A new version of myApp is available!&quot;</span>;
qDebug() <span style="color: #333333">&lt;&lt;</span> <span style="background-color: #fff0f0">&quot;The latest version is:&quot;</span>
<span style="color: #333333">&lt;&lt;</span> updater<span style="color: #333333">-&gt;</span>latestVersion();
qDebug() <span style="color: #333333">&lt;&lt;</span> <span style="background-color: #fff0f0">&quot;The change log of the new version is:</span><span style="color: #666666; font-weight: bold; background-color: #fff0f0">\n</span><span style="background-color: #fff0f0">&quot;</span>
<span style="color: #333333">&lt;&lt;</span> updater<span style="color: #333333">-&gt;</span>changeLog();
<span style="color: #333399; font-weight: bold">char</span> type;
<span style="color: #008800; font-weight: bold">while</span> (<span style="color: #007020">true</span>) {
cout <span style="color: #333333">&lt;&lt;</span> <span style="background-color: #fff0f0">&quot;Download the latest version [y/n]&quot;</span> <span style="color: #333333">&lt;&lt;</span> endl;
cin <span style="color: #333333">&gt;&gt;</span> type;
<span style="color: #008800; font-weight: bold">if</span> ((type <span style="color: #333333">==</span> <span style="color: #0044DD">&#39;y&#39;</span>) <span style="color: #333333">||</span> (type <span style="color: #333333">==</span> <span style="color: #0044DD">&#39;n&#39;</span>)) {
<span style="color: #008800; font-weight: bold">break</span>;
}
}
<span style="color: #008800; font-weight: bold">if</span> (type <span style="color: #333333">==</span> <span style="color: #0044DD">&#39;y&#39;</span>) {
updater<span style="color: #333333">-&gt;</span>downloadLatestVersion();
}
}
</pre></div>
#### Notes
## Running the example project
1. Navigate to the <code>Example</code> folder and open <code>example.pro</code> with [Qt Creator](http://qt-project.org/wiki/Category:Tools::QtCreator).
2. Compile the project and play with it <code>:)</code>
## Useful Links
+ [Project website](http://qsimpleupdater.sf.net)
+ [SourceForge Project](http://sf.net/p/qsimpleupdater)
+ [OpenHub Project](http://openhub.net/p/qsimpleupdater)
+ [Contact developer](mailto:alex.racotta@gmail.com)
## Donate
Donate [Bitcoins](http://bitcoin.org) to the project to keep it going!
> 1BdxESMayJAengjAkjipMwfWkiqZUztyhU