Commit f177e330 authored by Johnny Jazeix's avatar Johnny Jazeix

core, handle multiple downloads at the same time. Progress bar no more flickering

parent 000fff32
......@@ -280,7 +280,7 @@ Item {
target: DownloadManager
onDownloadStarted: content.value |= content.download
onDownloadFinished: content.value &= ~content.download
onAllDownloadsFinished: content.value &= ~content.download
onError: content.value &= ~content.download
}
......
......@@ -180,7 +180,7 @@ Item {
wrapMode: TextEdit.WordWrap
z: 2
height: 60 * ApplicationInfo.ratio
text: qsTr("Downloading ...")
text: qsTr("Downloading...")
}
Rectangle {
......@@ -293,8 +293,8 @@ Item {
downloadDialogProgress.value = 0;
}
onDownloadFinished: {
//console.log("dialog: DM reports finished: " + code);
onAllDownloadsFinished: {
//console.log("dialog: DM all reports finished");
downloadDialog.finished();
if (downloadDialog.reportSuccess
&& code != 1) // note: errors will be reported by the onError handler
......@@ -318,6 +318,10 @@ Item {
} else if (downloadDialog.autohide)
downloadDialog.shutdown();
}
onDownloadFinished: {
//console.log("dialog: DM reports finished: " + code);
}
}
}
......@@ -87,7 +87,7 @@ void DownloadManager::abortDownloads()
QMutableListIterator<DownloadJob*> iter(activeJobs);
while (iter.hasNext()) {
DownloadJob *job = iter.next();
if (job->reply != nullptr) {
if (!job->downloadFinished && job->reply != nullptr) {
disconnect(job->reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
disconnect(job->reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)));
......@@ -99,6 +99,7 @@ void DownloadManager::abortDownloads()
}
job->reply->deleteLater();
}
delete job;
iter.remove();
}
locker.unlock();
......@@ -244,7 +245,7 @@ bool DownloadManager::download(DownloadJob* job)
this, SLOT(handleError(QNetworkReply::NetworkError)));
if (job->url.fileName() != contentsFilename) {
connect(reply, &QNetworkReply::downloadProgress,
this, &DownloadManager::downloadProgress);
this, &DownloadManager::downloadInProgress);
emit downloadStarted(job->url.toString().remove(0, serverUrl.toString().length()));
}
......@@ -467,11 +468,33 @@ bool DownloadManager::areVoicesRegistered() const
return isDataRegistered(resource);
}
void DownloadManager::downloadInProgress(qint64 bytesReceived, qint64 bytesTotal) {
QNetworkReply *reply = dynamic_cast<QNetworkReply*>(sender());
DownloadJob *job = nullptr;
// don't call getJobByReply to not cause deadlock with mutex
for (auto activeJob : activeJobs) {
if (activeJob->reply == reply) {
job = activeJob;
break;
}
}
job->bytesReceived = bytesReceived;
job->bytesTotal = bytesTotal;
qint64 allJobsBytesReceived = 0;
qint64 allJobsBytesTotal = 0;
for (auto activeJob : activeJobs) {
allJobsBytesReceived += activeJob->bytesReceived;
allJobsBytesTotal += activeJob->bytesTotal;
}
emit downloadProgress(allJobsBytesReceived, allJobsBytesTotal);
}
void DownloadManager::downloadFinished()
{
QNetworkReply* reply = dynamic_cast<QNetworkReply*>(sender());
DownloadFinishedCode code = Success;
DownloadJob *job = getJobByReply(reply);
bool allFinished = false;
if (job->file.isOpen()) {
job->file.flush(); // note: important, or checksums might be wrong!
job->file.close();
......@@ -570,15 +593,27 @@ void DownloadManager::downloadFinished()
}
// none left, DownloadJob finished
job->downloadFinished = true;
job->downloadResult = code;
if (job->file.isOpen())
job->file.close();
{ // note: must remove before signalling downloadFinished(), otherwise race condition for the Qt.quit() case
QMutexLocker locker(&jobsMutex);
activeJobs.removeOne(job);
}
emit downloadFinished(code);
reply->deleteLater();
delete job;
allFinished = std::all_of(activeJobs.constBegin(), activeJobs.constEnd(),
[](const DownloadJob* job) { return job->downloadFinished;});
if(allFinished) {
QMutexLocker locker(&jobsMutex);
DownloadFinishedCode allCode = Success;
std::for_each(activeJobs.constBegin(), activeJobs.constEnd(),
[&allCode] (const DownloadJob *job) {
if(job->downloadResult == Error)
allCode = Error;
delete job;
});
activeJobs.clear();
emit allDownloadsFinished(allCode);
}
return;
outError:
......
......@@ -97,8 +97,16 @@ private:
QMap<QString,QString> contents; ///< checksum map for download verification
QList<QUrl> knownContentsUrls; ///< store already tried upstream Contents files (for infinite loop protection)
qint64 bytesReceived;
qint64 bytesTotal;
bool downloadFinished;
int downloadResult;
DownloadJob(const QUrl &u = QUrl()) : url(u), file(), reply(0),
queue(QList<QUrl>()) {}
queue(QList<QUrl>()),
bytesReceived(0),
bytesTotal(0),
downloadFinished(false),
downloadResult(0) {}
} DownloadJob;
QList<DownloadJob*> activeJobs; ///< track active jobs to allow for parallel downloads
......@@ -281,6 +289,15 @@ public:
public slots:
/** Emitted when a download in progressing.
*
* Job is retrieved using sender() method.
*
* @param bytesReceived Downloaded bytes for this job.
* @param bytesTotal Total bytes to download for this job.
*/
void downloadInProgress(qint64 bytesReceived, qint64 bytesTotal);
/**
* Updates a resource @p path from the upstream server unless prohibited
* by the settings and registers it if possible.
......@@ -364,6 +381,13 @@ signals:
*/
void downloadFinished(int code);
/** Emitted when all downloads have finished.
*
* If all downloads are successful, code is Success.
* Else if at least one download is in error, code is Error.
*/
void allDownloadsFinished(int code);
/** Emitted when a resource has been registered.
*
* @param resource Relative resource path of the registered resource.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment