download.cpp Example File
documentshare/download.cpp
#include "download.h"
#include "sharewidget.h"
#include <qdocumentgallery.h>
#include <qgalleryurlrequest.h>
#include <QtGui>
#include <QtNetwork>
Download::Download(QNetworkReply *networkReply, QDocumentGallery *gallery, QObject *parent)
: QObject(parent)
, downloadState(Downloading)
, currentDownloadProgress(0)
, maximumDownloadProgress(0)
, networkReply(networkReply)
, urlRequest(0)
{
connect(networkReply, SIGNAL(metaDataChanged()), this, SLOT(networkMetaDataChanged()));
connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
this, SLOT(networkProgress(qint64,qint64)));
connect(networkReply, SIGNAL(readyRead()), this, SLOT(networkReadyRead()));
connect(networkReply, SIGNAL(finished()), this, SLOT(networkFinished()));
urlRequest = new QGalleryUrlRequest(gallery, this);
urlRequest->setCreate(true);
connect(urlRequest, SIGNAL(progressChanged(int,int)), this, SLOT(urlRequestProgress(int,int)));
connect(urlRequest, SIGNAL(finished(int)), this, SLOT(urlRequestFinished(int)));
}
Download::~Download()
{
delete networkReply;
}
Download::State Download::state() const
{
return downloadState;
}
QVariant Download::itemId() const
{
return urlRequest->itemId();
}
QString Download::itemType() const
{
return urlRequest->itemType();
}
QString Download::displayName() const
{
return fileName;
}
int Download::currentProgress() const
{
return currentDownloadProgress;
}
int Download::maximumProgress() const
{
return maximumDownloadProgress;
}
void Download::networkMetaDataChanged()
{
if (!file.isOpen()) {
QByteArray disposition = networkReply->rawHeader("Content-Disposition");
if (!disposition.isEmpty()) {
int fileNameIndex = disposition.indexOf("filename=") + 9;
if (fileNameIndex >= 9) {
int semiColonIndex = disposition.indexOf(';', fileNameIndex);
fileName = semiColonIndex >= 0
? disposition.mid(fileNameIndex, semiColonIndex - fileNameIndex)
: disposition.mid(fileNameIndex);
if (fileName.startsWith(QLatin1Char('"'))) {
fileName = fileName.endsWith(QLatin1Char('"'))
? fileName.mid(1, fileName.length() - 2)
: fileName.mid(1);
} else if (fileName.endsWith(QLatin1Char('"'))) {
fileName.chop(1);
}
}
}
if (fileName.isEmpty()) {
fileName = networkReply->url().path().section(QLatin1Char('/'), -1);
if (fileName.isEmpty())
fileName = QLatin1String("unnamed_download");
}
QString filePath = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)
+ QLatin1Char('/')
+ fileName;
filePath = QFileDialog::getSaveFileName(0, tr("Save File"), filePath);
if (!filePath.isEmpty()) {
file.setFileName(filePath);
if (file.open(QIODevice::WriteOnly))
networkReadyRead();
else
networkReply->abort();
}
}
}
void Download::networkProgress(qint64 current, qint64 maximum)
{
currentDownloadProgress = current;
maximumDownloadProgress = maximum;
emit progressChanged(this);
}
void Download::networkReadyRead()
{
if (file.isOpen()) {
char buffer[4096];
qint64 bytesRead = networkReply->read(buffer, 4096);
while (bytesRead > 0) {
file.write(buffer, bytesRead);
bytesRead = networkReply->read(buffer, 4096);
}
}
}
void Download::networkFinished()
{
if (networkReply->error() != QNetworkReply::NoError) {
if (file.isOpen()) {
file.close();
file.remove();
}
downloadState = DownloadError;
} else {
networkMetaDataChanged();
networkReadyRead();
file.close();
downloadState = Finalizing;
urlRequest->setItemUrl(QUrl::fromLocalFile(file.fileName()));
urlRequest->execute();
}
emit stateChanged(this);
}
void Download::urlRequestProgress(int current, int maximum)
{
currentDownloadProgress = current;
maximumDownloadProgress = maximum;
emit progressChanged(this);
}
void Download::urlRequestFinished(int result)
{
if (result == QGalleryAbstractRequest::Succeeded) {
downloadState = Finished;
} else {
qWarning("URL request failed %d", result);
downloadState = ItemError;
}
emit stateChanged(this);
}