1 // Copyright (C) 2012-2019 The VPaint Developers.
2 // See the COPYRIGHT file at the top-level directory of this distribution
3 // and at https://github.com/dalboris/vpaint/blob/master/COPYRIGHT
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #include "UpdateCheck.h"
18 
19 #include <QUrl>
20 #include <QtNetwork>
21 #include <QDebug>
22 
23 #include "Application.h"
24 #include "Global.h"
25 #include "UpdateCheckDialog.h"
26 
UpdateCheck(QWidget * parent)27 UpdateCheck::UpdateCheck(QWidget * parent) :
28     reply_(0),
29     isReady_(false)
30 {
31     // Initialize variables
32     versionToCheck_ = global()->settings().checkVersion();
33     if(versionToCheck_ < Version(qApp->applicationVersion()) && versionToCheck_ != Version()) {
34         global()->settings().setCheckVersion(Version(qApp->applicationVersion()));
35         versionToCheck_ = global()->settings().checkVersion();
36     }
37     networkManager_ = new QNetworkAccessManager();
38     parent_ = parent;
39 
40     checkForUpdates();
41 }
42 
~UpdateCheck()43 UpdateCheck::~UpdateCheck()
44 {
45     delete networkManager_;
46 }
47 
versionChecked() const48 Version UpdateCheck::versionChecked() const
49 {
50     return versionToCheck_;
51 }
52 
latestVersion() const53 Version UpdateCheck::latestVersion() const
54 {
55     return latestVersion_;
56 }
57 
checkForUpdates()58 void UpdateCheck::checkForUpdates()
59 {
60     // Return if a request is already in progress
61     if(reply_) return;
62 
63     // Return if the user has asked not to check for updates
64     if(versionToCheck_ == Version()) return;
65 
66     // Set query
67     QUrlQuery urlQuery;
68     QUrl url = QUrl("http://vpaint.org/latestversion.php");
69     QNetworkRequest networkRequest(url);
70     networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
71                              "application/x-www-form-urlencoded; charset=utf-8");
72 
73     // Send query
74     QString urlQueryString = urlQuery.toString(QUrl::FullyEncoded);
75     urlQueryString.replace('+', "%2B");
76     reply_ = networkManager_->post(networkRequest, urlQueryString.toUtf8());
77 
78     // Connection to process reply
79     connect(reply_, SIGNAL(finished()), this, SLOT(requestFinished_()));
80 }
81 
requestFinished_()82 void UpdateCheck::requestFinished_()
83 {
84     // Return if not ready to display dialog
85     if(!isReady_) return;
86 
87     // Check for errors
88     if(reply_->error() != QNetworkReply::NoError)
89     {
90         qDebug() << "Warning: could not check for updates. " << reply_->errorString();
91         return;
92     }
93 
94     // Read and parse response
95     latestVersion_ = Version(QString(reply_->readAll()));
96 
97     // Compare versions
98     if(versionToCheck_ < latestVersion_)
99     {
100         // Create dialog with latest version
101         dialog_ = new UpdateCheckDialog(latestVersion_.toString(), parent_, Qt::Dialog);
102         dialog_->setAttribute(Qt::WA_DeleteOnClose);
103         connect(dialog_, SIGNAL(accepted()), this, SLOT(updateSettings_()));
104 
105         // Display dialog
106         dialog_->exec();
107     }
108 
109     reply_->deleteLater();
110 
111     isReady_ = false;
112 }
113 
showWhenReady()114 void UpdateCheck::showWhenReady()
115 {
116     if(reply_ && reply_->isFinished())
117     {
118         isReady_ = true;
119         requestFinished_();
120     }
121     else {
122         isReady_ = true;
123     }
124 }
125 
updateSettings_()126 void UpdateCheck::updateSettings_() {
127     if(dialog_->stopChecking())
128     {
129         global()->settings().setCheckVersion(Version());
130     }
131     else if(dialog_->skipVersion()) {
132         global()->settings().setCheckVersion(latestVersion_);
133     }
134 }
135