summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2018-01-30 09:28:23 +0200
committerKatja Marttila <katja.marttila@qt.io>2018-02-08 12:55:47 +0200
commitfff2c98f4a7d8e4e903232b08f72aeffd5e0cda1 (patch)
tree901763a343a2085b6c21c314f1b789290ceaeb63 /src/libs
parent0797935d299d0da007cae0ab89ee9ceadc41d670 (diff)
parente6c28c7fe32de1dca539c987e1c0a26f48ab0483 (diff)
Merge remote-tracking branch 'origin/3.0' into master
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/copydirectoryoperation.cpp4
-rw-r--r--src/libs/installer/environmentvariablesoperation.cpp51
-rw-r--r--src/libs/installer/packagemanagercore.cpp6
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp4
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.cpp7
-rw-r--r--src/libs/installer/remoteclient_p.h56
-rw-r--r--src/libs/installer/scriptengine.cpp5
-rw-r--r--src/libs/kdtools/filedownloader.cpp233
-rw-r--r--src/libs/kdtools/filedownloader.h13
-rw-r--r--src/libs/kdtools/filedownloader_p.h3
10 files changed, 321 insertions, 61 deletions
diff --git a/src/libs/installer/copydirectoryoperation.cpp b/src/libs/installer/copydirectoryoperation.cpp
index cdd6da6ab..e83af07e1 100644
--- a/src/libs/installer/copydirectoryoperation.cpp
+++ b/src/libs/installer/copydirectoryoperation.cpp
@@ -85,7 +85,7 @@ bool CopyDirectoryOperation::performOperation()
if (!dir.exists() || !dir.isDir()) {
setError(InvalidArguments);
setErrorString(tr("Invalid argument in %1: Directory \"%2\" is invalid.").arg(name())
- .arg(QDir::toNativeSeparators(sourcePath)));
+ .arg(QDir::toNativeSeparators(dir.absolutePath())));
return false;
}
}
@@ -157,7 +157,7 @@ bool CopyDirectoryOperation::undoOperation()
setErrorString(tr("Cannot remove file \"%1\".").arg(QDir::toNativeSeparators(file)));
return false;
}
- dir.rmpath(QFileInfo(file).absolutePath());
+ dir.rmdir(QFileInfo(file).absolutePath());
emit outputTextChanged(file);
}
diff --git a/src/libs/installer/environmentvariablesoperation.cpp b/src/libs/installer/environmentvariablesoperation.cpp
index b80951d2b..7a8dbfb5a 100644
--- a/src/libs/installer/environmentvariablesoperation.cpp
+++ b/src/libs/installer/environmentvariablesoperation.cpp
@@ -65,6 +65,48 @@ static void broadcastEnvironmentChange()
namespace {
+bool handleRegExpandSz(const QString &regPath, const QString &name,
+ const QString &value, QString *errorString,
+ bool *error)
+{
+ bool setAsExpandSZ = false;
+#ifdef Q_OS_WIN
+ // Account for when it is originally REG_EXPAND_SZ as we don't want
+ // to lose this setting (see Path environment variable)
+ const bool isLocalKey = regPath.startsWith(QStringLiteral("HKEY_LOCAL"));
+ HKEY hkey = isLocalKey ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+ // Drop the HKEY...\\ part
+ const QString keyPath = regPath.mid(isLocalKey ? 19 : 18, -1);
+ HKEY handle;
+ LONG res = RegOpenKeyEx(hkey, reinterpret_cast<const wchar_t *>(keyPath.utf16()), 0,
+ KEY_READ, &handle);
+ if (res == ERROR_SUCCESS) {
+ DWORD dataType;
+ DWORD dataSize;
+ res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(name.utf16()), 0,
+ &dataType, 0, &dataSize);
+ setAsExpandSZ = (res == ERROR_SUCCESS) && (dataType == REG_EXPAND_SZ);
+ if (setAsExpandSZ) {
+ RegCloseKey(handle);
+ res = RegOpenKeyEx(hkey, reinterpret_cast<const wchar_t *>(keyPath.utf16()), 0,
+ KEY_SET_VALUE, &handle);
+ if (res == ERROR_SUCCESS) {
+ const QByteArray data(reinterpret_cast<const char *>(value.utf16()),
+ (value.length() + 1) * 2);
+ res = RegSetValueEx(handle, reinterpret_cast<const wchar_t *>(name.utf16()), 0, REG_EXPAND_SZ,
+ reinterpret_cast<const unsigned char*>(data.constData()), data.size());
+ RegCloseKey(handle);
+ }
+ if (res != ERROR_SUCCESS) {
+ *errorString = UpdateOperation::tr("Cannot write to registry path %1.").arg(regPath);
+ *error = true;
+ }
+ }
+ }
+#endif
+ return setAsExpandSZ;
+}
+
template <typename SettingsType>
UpdateOperation::Error writeSetting(const QString &regPath,
const QString &name,
@@ -82,6 +124,10 @@ UpdateOperation::Error writeSetting(const QString &regPath,
// remember old value for undo
*oldValue = registry.value(name).toString();
+ bool error = false;
+ if (handleRegExpandSz(regPath, name, value, errorString, &error))
+ return error ? UpdateOperation::UserDefinedError : UpdateOperation::NoError;
+
// set the new value
registry.setValue(name, value);
registry.sync();
@@ -108,6 +154,11 @@ UpdateOperation::Error undoSetting(const QString &regPath,
}
if (actual != value) //key changed, don't undo
return UpdateOperation::UserDefinedError;
+
+ bool error = false;
+ if (handleRegExpandSz(regPath, name, oldValue, errorString, &error))
+ return error ? UpdateOperation::UserDefinedError : UpdateOperation::NoError;
+
QString dontcare;
return writeSetting<SettingsType>(regPath, name, oldValue, errorString, &dontcare);
}
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 58f7a8145..9b9c986e0 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -1324,6 +1324,12 @@ bool PackageManagerCore::setDefaultPageVisible(int page, bool visible)
Sets a validator for the custom page specified by \a name and \a callbackName
for the component \a component.
+ When using this, \a name has to match a dynamic page starting with \c Dynamic. For example, if the page
+ is called DynamicReadyToInstallWidget, then \a name should be set to \c ReadyToInstallWidget. The
+ \a callbackName should be set to a function that returns a boolean. When the \c Next button is pressed
+ on the custom page, then it will call the \a callbackName function. If this returns \c true, then it will
+ move to the next page.
+
\sa {installer::setValidatorForCustomPage}{installer.setValidatorForCustomPage}
\sa setValidatorForCustomPageRequested()
*/
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index fb1082294..57f430778 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -1197,8 +1197,8 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
performOperationThreaded(op, Backup);
performOperationThreaded(op);
- // copy application icons if it exists
- const QString icon = QFileInfo(QCoreApplication::applicationFilePath()).baseName()
+ // copy application icons if it exists.
+ const QString icon = QFileInfo(QCoreApplication::applicationFilePath()).fileName()
+ QLatin1String(".icns");
op = createOwnedOperation(QLatin1String("Copy"));
op->setArguments(QStringList() << (sourceAppDirPath + QLatin1String("/../Resources/") + icon)
diff --git a/src/libs/installer/packagemanagerproxyfactory.cpp b/src/libs/installer/packagemanagerproxyfactory.cpp
index 98aef7d9a..93135aa1f 100644
--- a/src/libs/installer/packagemanagerproxyfactory.cpp
+++ b/src/libs/installer/packagemanagerproxyfactory.cpp
@@ -62,13 +62,6 @@ QList<QNetworkProxy> PackageManagerProxyFactory::queryProxy(const QNetworkProxyQ
QList<QNetworkProxy> list;
if (settings.proxyType() == Settings::SystemProxy) {
-#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
- QUrl proxyUrl = QUrl::fromUserInput(QString::fromUtf8(qgetenv("http_proxy")));
- if (proxyUrl.isValid()) {
- return list << QNetworkProxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyUrl.port(),
- proxyUrl.userName(), proxyUrl.password());
- }
-#endif
QList<QNetworkProxy> systemProxies = systemProxyForQuery(query);
auto proxyIter = systemProxies.begin();
diff --git a/src/libs/installer/remoteclient_p.h b/src/libs/installer/remoteclient_p.h
index d1e873d43..ed1731342 100644
--- a/src/libs/installer/remoteclient_p.h
+++ b/src/libs/installer/remoteclient_p.h
@@ -125,32 +125,38 @@ public:
if (!started) {
if (m_authorizationFallbackDisabled) {
- MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("AuthorizationError"),
- QCoreApplication::translate("RemoteClient", "Cannot get authorization."),
- QCoreApplication::translate("RemoteClient",
- "Cannot get authorization that is needed for continuing the installation.\n\n"
- "Please start the setup program as a user with the appropriate rights.\n"
- "Or accept the elevation of access rights if being asked."));
- return;
+ QMessageBox::Button res = QMessageBox::Retry;
+ while (res == QMessageBox::Retry && !started) {
+ res = MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("AuthorizationError"),
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization."),
+ QCoreApplication::translate("RemoteClient",
+ "Cannot get authorization that is needed for continuing the installation.\n\n"
+ "Please start the setup program as a user with the appropriate rights.\n"
+ "Or accept the elevation of access rights if being asked."),
+ QMessageBox::Abort | QMessageBox::Retry, QMessageBox::Retry);
+ if (res == QMessageBox::Retry)
+ started = AdminAuthorization::execute(0, m_serverCommand, m_serverArguments);
+ }
+ } else {
+ // something went wrong with authorizing, either user pressed cancel or entered
+ // wrong password
+ const QString fallback = m_serverCommand + QLatin1String(" ") + m_serverArguments
+ .join(QLatin1String(" "));
+
+ const QMessageBox::Button res =
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("AuthorizationError"),
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization."),
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization that "
+ "is needed for continuing the installation.\n Either abort the "
+ "installation or use the fallback solution by running\n\n%1\n\nas a user "
+ "with the appropriate rights and then clicking OK.").arg(fallback),
+ QMessageBox::Abort | QMessageBox::Ok, QMessageBox::Ok);
+
+ if (res == QMessageBox::Ok)
+ started = true;
}
- // something went wrong with authorizing, either user pressed cancel or entered
- // wrong password
- const QString fallback = m_serverCommand + QLatin1String(" ") + m_serverArguments
- .join(QLatin1String(" "));
-
- const QMessageBox::Button res =
- MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("AuthorizationError"),
- QCoreApplication::translate("RemoteClient", "Cannot get authorization."),
- QCoreApplication::translate("RemoteClient", "Cannot get authorization that "
- "is needed for continuing the installation.\n Either abort the "
- "installation or use the fallback solution by running\n\n%1\n\nas a user "
- "with the appropriate rights and then clicking OK.").arg(fallback),
- QMessageBox::Abort | QMessageBox::Ok, QMessageBox::Ok);
-
- if (res == QMessageBox::Ok)
- started = true;
}
} else {
started = QInstaller::startDetached(m_serverCommand, m_serverArguments,
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
index 59f71a52c..28f91a394 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -401,8 +401,9 @@ QJSValue ScriptEngine::loadInContext(const QString &context, const QString &file
if (scriptContext.isError()) {
throw Error(tr("Exception while loading the component script \"%1\": %2").arg(
QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath()),
- scriptContext.toString().isEmpty() ?
- tr("Unknown error.") : scriptContext.toString()));
+ scriptContext.toString().isEmpty() ? tr("Unknown error.") : scriptContext.toString() +
+ QStringLiteral(" ") + tr("on line number: ") +
+ scriptContext.property(QStringLiteral("lineNumber")).toString()));
}
return scriptContext;
}
diff --git a/src/libs/kdtools/filedownloader.cpp b/src/libs/kdtools/filedownloader.cpp
index 1a0a8f1c2..87dfd21b4 100644
--- a/src/libs/kdtools/filedownloader.cpp
+++ b/src/libs/kdtools/filedownloader.cpp
@@ -181,8 +181,13 @@ struct KDUpdater::FileDownloader::Private
, m_assumedSha1Sum("")
, autoRemove(true)
, m_speedTimerInterval(100)
+ , m_downloadDeadlineTimerInterval(30000)
+ , m_downloadPaused(false)
+ , m_downloadResumed(false)
, m_bytesReceived(0)
, m_bytesToReceive(0)
+ , m_bytesBeforeResume(0)
+ , m_totalBytesBeforeResume(0)
, m_currentSpeedBin(0)
, m_sampleIndex(0)
, m_downloadSpeed(0)
@@ -207,11 +212,18 @@ struct KDUpdater::FileDownloader::Private
bool autoRemove;
bool followRedirect;
- QBasicTimer m_timer;
+ QBasicTimer m_speedIntervalTimer;
int m_speedTimerInterval;
+ QBasicTimer m_downloadDeadlineTimer;
+ int m_downloadDeadlineTimerInterval;
+ bool m_downloadPaused;
+ bool m_downloadResumed;
+
qint64 m_bytesReceived;
qint64 m_bytesToReceive;
+ qint64 m_bytesBeforeResume;
+ qint64 m_totalBytesBeforeResume;
mutable qint64 m_samples[50];
mutable qint64 m_currentSpeedBin;
@@ -382,8 +394,8 @@ void KDUpdater::FileDownloader::cancelDownload()
*/
void KDUpdater::FileDownloader::runDownloadSpeedTimer()
{
- if (!d->m_timer.isActive())
- d->m_timer.start(d->m_speedTimerInterval, this);
+ if (!d->m_speedIntervalTimer.isActive())
+ d->m_speedIntervalTimer.start(d->m_speedTimerInterval, this);
}
/*!
@@ -391,7 +403,97 @@ void KDUpdater::FileDownloader::runDownloadSpeedTimer()
*/
void KDUpdater::FileDownloader::stopDownloadSpeedTimer()
{
- d->m_timer.stop();
+ d->m_speedIntervalTimer.stop();
+}
+
+/*!
+ Restarts the download deadline timer.
+*/
+void KDUpdater::FileDownloader::runDownloadDeadlineTimer()
+{
+ stopDownloadDeadlineTimer();
+ d->m_downloadDeadlineTimer.start(d->m_downloadDeadlineTimerInterval, this);
+}
+
+/*!
+ Stops the download deadline timer.
+*/
+void KDUpdater::FileDownloader::stopDownloadDeadlineTimer()
+{
+ d->m_downloadDeadlineTimer.stop();
+}
+
+/*!
+ Sets the download into a paused state.
+*/
+void KDUpdater::FileDownloader::setDownloadPaused(bool paused)
+{
+ d->m_downloadPaused = paused;
+}
+
+/*!
+ Gets the download paused state.
+*/
+bool KDUpdater::FileDownloader::isDownloadPaused()
+{
+ return d->m_downloadPaused;
+}
+
+/*!
+ Sets the download into a paused state.
+*/
+void KDUpdater::FileDownloader::setDownloadResumed(bool resumed)
+{
+ d->m_downloadResumed = resumed;
+}
+
+/*!
+ Gets the download resumed state.
+*/
+bool KDUpdater::FileDownloader::isDownloadResumed()
+{
+ return d->m_downloadResumed;
+}
+
+/*!
+ Gets the amount of bytes downloaded before download resume.
+*/
+qint64 KDUpdater::FileDownloader::bytesDownloadedBeforeResume()
+{
+ return d->m_bytesBeforeResume;
+}
+
+/*!
+ Gets the total amount of bytes downloaded before download resume.
+*/
+qint64 KDUpdater::FileDownloader::totalBytesDownloadedBeforeResume()
+{
+ return d->m_totalBytesBeforeResume;
+}
+
+/*!
+ Clears the amount of bytes downloaded before download resume.
+*/
+void KDUpdater::FileDownloader::clearBytesDownloadedBeforeResume()
+{
+ d->m_bytesBeforeResume = 0;
+ d->m_totalBytesBeforeResume = 0;
+}
+
+/*!
+ Updates the amount of bytes downloaded before download resume.
+*/
+void KDUpdater::FileDownloader::updateBytesDownloadedBeforeResume(qint64 bytes)
+{
+ d->m_bytesBeforeResume += bytes;
+}
+
+/*!
+ Updates the total amount of bytes downloaded before download resume.
+*/
+void KDUpdater::FileDownloader::updateTotalBytesDownloadedBeforeResume()
+{
+ d->m_totalBytesBeforeResume = d->m_bytesBeforeResume;
}
/*!
@@ -407,7 +509,15 @@ void KDUpdater::FileDownloader::addSample(qint64 sample)
*/
int KDUpdater::FileDownloader::downloadSpeedTimerId() const
{
- return d->m_timer.timerId();
+ return d->m_speedIntervalTimer.timerId();
+}
+
+/*!
+ Returns the download deadline timer ID.
+*/
+int KDUpdater::FileDownloader::downloadDeadlineTimerId() const
+{
+ return d->m_downloadDeadlineTimer.timerId();
}
/*!
@@ -792,7 +902,6 @@ void KDUpdater::LocalFileDownloader::timerEvent(QTimerEvent *event)
}
addSample(numRead);
addCheckSumData(buffer.data(), numRead);
-
if (numRead > 0) {
setProgress(d->source->pos(), d->source->size());
emit downloadProgress(calcProgress(d->source->pos(), d->source->size()));
@@ -1050,21 +1159,31 @@ struct KDUpdater::HttpDownloader::Private
HttpDownloader *const q;
QNetworkAccessManager manager;
QNetworkReply *http;
+ QUrl sourceUrl;
QFile *destination;
QString destFileName;
bool downloaded;
bool aborted;
int m_authenticationCount;
- void shutDown()
+ void shutDown(bool closeDestination = true)
{
- disconnect(http, &QNetworkReply::finished, q, &HttpDownloader::httpReqFinished);
- http->deleteLater();
+ if (http) {
+ disconnect(http, &QNetworkReply::finished, q, &HttpDownloader::httpReqFinished);
+ disconnect(http, &QNetworkReply::downloadProgress,
+ q, &HttpDownloader::httpReadProgress);
+ void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) = &QNetworkReply::error;
+
+ disconnect(http, errorSignal, q, &HttpDownloader::httpError);
+ http->deleteLater();
+ }
http = 0;
- destination->close();
- destination->deleteLater();
- destination = 0;
- q->resetCheckSumData();
+ if (closeDestination) {
+ destination->close();
+ destination->deleteLater();
+ destination = 0;
+ q->resetCheckSumData();
+ }
}
};
@@ -1081,6 +1200,9 @@ KDUpdater::HttpDownloader::HttpDownloader(QObject *parent)
#endif
connect(&d->manager, &QNetworkAccessManager::authenticationRequired,
this, &HttpDownloader::onAuthenticationRequired);
+ connect(&d->manager, &QNetworkAccessManager::networkAccessibleChanged,
+ this, &HttpDownloader::onNetworkAccessibleChanged);
+
}
/*!
@@ -1123,6 +1245,7 @@ void KDUpdater::HttpDownloader::doDownload()
startDownload(url());
runDownloadSpeedTimer();
+ runDownloadDeadlineTimer();
}
/*!
@@ -1152,6 +1275,8 @@ KDUpdater::HttpDownloader *KDUpdater::HttpDownloader::clone(QObject *parent) con
void KDUpdater::HttpDownloader::httpReadyRead()
{
+ if (d->http == 0 || d->destination == 0)
+ return;
static QByteArray buffer(16384, '\0');
while (d->http->bytesAvailable()) {
const qint64 read = d->http->read(buffer.data(), buffer.size());
@@ -1170,6 +1295,7 @@ void KDUpdater::HttpDownloader::httpReadyRead()
}
addSample(written);
addCheckSumData(buffer.data(), read);
+ updateBytesDownloadedBeforeResume(written);
}
}
@@ -1194,6 +1320,10 @@ void KDUpdater::HttpDownloader::cancelDownload()
void KDUpdater::HttpDownloader::httpDone(bool error)
{
if (error) {
+ if (isDownloadResumed()) {
+ d->shutDown(false);
+ return;
+ }
QString err;
if (d->http) {
err = d->http->errorString();
@@ -1206,10 +1336,11 @@ void KDUpdater::HttpDownloader::httpDone(bool error)
d->aborted = false;
setDownloadCanceled();
} else {
- setDownloadAborted(err);
+ d->shutDown(false);
+ return;
}
}
- //PENDING: what about the non-error case??
+ setDownloadResumed(false);
}
/*!
@@ -1223,6 +1354,7 @@ void KDUpdater::HttpDownloader::onError()
delete d->destination;
d->destination = 0;
stopDownloadSpeedTimer();
+ stopDownloadDeadlineTimer();
}
/*!
@@ -1232,12 +1364,16 @@ void KDUpdater::HttpDownloader::onError()
void KDUpdater::HttpDownloader::onSuccess()
{
d->downloaded = true;
- d->destFileName = d->destination->fileName();
- if (QTemporaryFile *file = dynamic_cast<QTemporaryFile *>(d->destination))
- file->setAutoRemove(false);
+ if (d->destination) {
+ d->destFileName = d->destination->fileName();
+ if (QTemporaryFile *file = dynamic_cast<QTemporaryFile *>(d->destination))
+ file->setAutoRemove(false);
+ }
delete d->destination;
d->destination = 0;
stopDownloadSpeedTimer();
+ stopDownloadDeadlineTimer();
+ setDownloadResumed(false);
}
void KDUpdater::HttpDownloader::httpReqFinished()
@@ -1266,9 +1402,11 @@ void KDUpdater::HttpDownloader::httpReqFinished()
}
}
httpReadyRead();
- d->destination->flush();
+ if (d->destination)
+ d->destination->flush();
setDownloadCompleted();
- d->http->deleteLater();
+ if (d->http)
+ d->http->deleteLater();
d->http = 0;
}
}
@@ -1281,8 +1419,16 @@ void KDUpdater::HttpDownloader::httpReadProgress(qint64 done, qint64 total)
return; // if we are a redirection, do not emit the progress
}
- setProgress(done, total);
- emit downloadProgress(calcProgress(done, total));
+ if (isDownloadResumed())
+ setProgress(done + totalBytesDownloadedBeforeResume(),
+ total + totalBytesDownloadedBeforeResume());
+ else
+ setProgress(done, total);
+ runDownloadDeadlineTimer();
+ if (isDownloadResumed())
+ emit downloadProgress(calcProgress(done + totalBytesDownloadedBeforeResume(), total + totalBytesDownloadedBeforeResume()));
+ else
+ emit downloadProgress(calcProgress(done, total));
}
/*!
@@ -1295,15 +1441,19 @@ void KDUpdater::HttpDownloader::timerEvent(QTimerEvent *event)
emitDownloadStatus();
emitDownloadProgress();
emitEstimatedDownloadTime();
+ } else if (event->timerId() == downloadDeadlineTimerId()) {
+ d->shutDown(false);
+ resumeDownload();
}
}
void KDUpdater::HttpDownloader::startDownload(const QUrl &url)
{
+ d->sourceUrl = url;
d->m_authenticationCount = 0;
d->manager.setProxyFactory(proxyFactory());
+ clearBytesDownloadedBeforeResume();
d->http = d->manager.get(QNetworkRequest(url));
-
connect(d->http, &QIODevice::readyRead, this, &HttpDownloader::httpReadyRead);
connect(d->http, &QNetworkReply::downloadProgress,
this, &HttpDownloader::httpReadProgress);
@@ -1329,6 +1479,28 @@ void KDUpdater::HttpDownloader::startDownload(const QUrl &url)
}
}
+void KDUpdater::HttpDownloader::resumeDownload()
+{
+ updateTotalBytesDownloadedBeforeResume();
+ d->m_authenticationCount = 0;
+ QNetworkRequest request(d->sourceUrl);
+
+ request.setRawHeader(QByteArray("Range"),
+ QString(QStringLiteral("bytes=%1-"))
+ .arg(bytesDownloadedBeforeResume())
+ .toLatin1());
+ setDownloadResumed(true);
+ d->http = d->manager.get(request);
+ connect(d->http, &QIODevice::readyRead, this, &HttpDownloader::httpReadyRead);
+ connect(d->http, &QNetworkReply::downloadProgress,
+ this, &HttpDownloader::httpReadProgress);
+ connect(d->http, &QNetworkReply::finished, this, &HttpDownloader::httpReqFinished);
+ void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) = &QNetworkReply::error;
+ connect(d->http, errorSignal, this, &HttpDownloader::httpError);
+ runDownloadSpeedTimer();
+ runDownloadDeadlineTimer();
+}
+
void KDUpdater::HttpDownloader::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
{
Q_UNUSED(reply)
@@ -1366,6 +1538,21 @@ void KDUpdater::HttpDownloader::onAuthenticationRequired(QNetworkReply *reply, Q
}
}
+void KDUpdater::HttpDownloader::onNetworkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible)
+{
+ if (accessible == QNetworkAccessManager::NotAccessible) {
+ d->shutDown(false);
+ setDownloadPaused(true);
+ setDownloadResumed(false);
+ stopDownloadDeadlineTimer();
+ } else if (accessible == QNetworkAccessManager::Accessible) {
+ if (isDownloadPaused()) {
+ setDownloadPaused(false);
+ resumeDownload();
+ }
+ }
+}
+
#ifndef QT_NO_SSL
#include "messageboxhandler.h"
diff --git a/src/libs/kdtools/filedownloader.h b/src/libs/kdtools/filedownloader.h
index 8c73cbeb0..ede20dcfa 100644
--- a/src/libs/kdtools/filedownloader.h
+++ b/src/libs/kdtools/filedownloader.h
@@ -115,8 +115,21 @@ protected:
void runDownloadSpeedTimer();
void stopDownloadSpeedTimer();
+ void runDownloadDeadlineTimer();
+ void stopDownloadDeadlineTimer();
+ void setDownloadPaused(bool paused);
+ bool isDownloadPaused();
+ void setDownloadResumed(bool resumed);
+ bool isDownloadResumed();
+ qint64 bytesDownloadedBeforeResume();
+ qint64 totalBytesDownloadedBeforeResume();
+ void clearBytesDownloadedBeforeResume();
+ void updateBytesDownloadedBeforeResume(qint64 bytes);
+ void updateTotalBytesDownloadedBeforeResume();
+
void addSample(qint64 sample);
int downloadSpeedTimerId() const;
+ int downloadDeadlineTimerId() const;
void setProgress(qint64 bytesReceived, qint64 bytesToReceive);
void emitDownloadSpeed();
diff --git a/src/libs/kdtools/filedownloader_p.h b/src/libs/kdtools/filedownloader_p.h
index f5a80c432..41a430554 100644
--- a/src/libs/kdtools/filedownloader_p.h
+++ b/src/libs/kdtools/filedownloader_p.h
@@ -32,6 +32,7 @@
#include "filedownloader.h"
#include <QtNetwork/QNetworkReply>
+#include <QNetworkAccessManager>
// these classes are not a part of the public API
@@ -128,11 +129,13 @@ private Q_SLOTS:
void httpDone(bool error);
void httpReqFinished();
void onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
+ void onNetworkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible);
#ifndef QT_NO_SSL
void onSslErrors(QNetworkReply* reply, const QList<QSslError> &errors);
#endif
private:
void startDownload(const QUrl &url);
+ void resumeDownload();
private:
struct Private;