First commit
This commit is contained in:
parent
9d044e370f
commit
5180987ec1
4
Authors.txt
Executable file
4
Authors.txt
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
QSIMPLEUPDATER AUTHORS
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Alex Spataru <alex_spataru@outlook.com>
|
96
Example/example.cpp
Normal file
96
Example/example.cpp
Normal 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
31
Example/example.h
Normal 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
10
Example/example.pro
Executable 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
272
Example/example.pro.user
Normal 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
90
Example/example.ui
Normal 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 "Check for Updates" 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>
|
1
LICENSE → License.txt
Normal file → Executable file
1
LICENSE → License.txt
Normal file → Executable file
@ -163,4 +163,3 @@ 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.
|
||||||
|
|
24
QSimpleUpdater/qsimpleupdater.pri
Executable file
24
QSimpleUpdater/qsimpleupdater.pri
Executable 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
|
||||||
|
}
|
1
QSimpleUpdater/src/QSimpleUpdater
Normal file
1
QSimpleUpdater/src/QSimpleUpdater
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "qsimpleupdater.h"
|
260
QSimpleUpdater/src/qsimpleupdater.cpp
Executable file
260
QSimpleUpdater/src/qsimpleupdater.cpp
Executable 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);
|
||||||
|
}
|
60
QSimpleUpdater/src/qsimpleupdater.h
Executable file
60
QSimpleUpdater/src/qsimpleupdater.h
Executable 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
138
Readme.md
Executable 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 <QSimpleUpdater></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">"1.2.3"</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">"http://myapp.com/downloads/latest.dmg"</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">"http://myapp.com/downloads/latest.exe"</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">"http://myapp.com/downloads/latest.tar.gz"</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">-></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">-></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">-></span>setReferenceUrl(QUrl(<span style="background-color: #fff0f0">"http://myapp.com/latest.txt"</span>));
|
||||||
|
|
||||||
|
<span style="color: #888888">// Tell the updater where to download the changelog...</span>
|
||||||
|
updater<span style="color: #333333">-></span>setChangelogUrl(QUrl(<span style="background-color: #fff0f0">"http://myapp.com/changelog.txt"</span>));
|
||||||
|
|
||||||
|
<span style="color: #888888">// Check for updates....</span>
|
||||||
|
updater<span style="color: #333333">-></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"><<</span> <span style="background-color: #fff0f0">"A new version of myApp is available!"</span>;
|
||||||
|
qDebug() <span style="color: #333333"><<</span> <span style="background-color: #fff0f0">"The latest version is:"</span>
|
||||||
|
<span style="color: #333333"><<</span> updater<span style="color: #333333">-></span>latestVersion();
|
||||||
|
qDebug() <span style="color: #333333"><<</span> <span style="background-color: #fff0f0">"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">"</span>
|
||||||
|
<span style="color: #333333"><<</span> updater<span style="color: #333333">-></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"><<</span> <span style="background-color: #fff0f0">"Download the latest version [y/n]"</span> <span style="color: #333333"><<</span> endl;
|
||||||
|
cin <span style="color: #333333">>></span> type;
|
||||||
|
|
||||||
|
<span style="color: #008800; font-weight: bold">if</span> ((type <span style="color: #333333">==</span> <span style="color: #0044DD">'y'</span>) <span style="color: #333333">||</span> (type <span style="color: #333333">==</span> <span style="color: #0044DD">'n'</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">'y'</span>) {
|
||||||
|
updater<span style="color: #333333">-></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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user