Files
wagic/projects/mtg/include/qt/filedownloader.h
2015-09-26 21:52:07 +02:00

148 lines
3.9 KiB
C++

#ifndef FILEDOWNLOADER_H
#define FILEDOWNLOADER_H
#include <QObject>
#include <QByteArray>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTemporaryFile>
#ifdef QT_WIDGET
#include <QProgressDialog>
#include <QPushButton>
#include <QCoreApplication>
#else
#include <qdeclarative.h>
#endif //QT_WIDGET
class FileDownloader :
#ifdef QT_WIDGET
public QProgressDialog
#else
public QObject
#endif //QT_WIDGET
{
Q_OBJECT
Q_PROPERTY(qint64 received READ received NOTIFY receivedChanged)
Q_PROPERTY(QString status READ getStatus NOTIFY statusChanged)
Q_PROPERTY(DownloadState state READ getState NOTIFY stateChanged )
Q_PROPERTY(QString state_string READ getStateString NOTIFY stateStringChanged )
Q_ENUMS(DownloadState)
public:
enum DownloadState {
NETWORK_ERROR,
DOWNLOADING_HASH,
DOWNLOADING_FILE,
DOWNLOADED
} ;
explicit FileDownloader(QString localPath, QString targetFile, QObject *parent = 0);
virtual ~FileDownloader();
qint64 received() const {return m_received;};
QString getStatus() {return m_status;};
DownloadState getState() {
return m_state;
};
QString getStateString() {
if(m_state == DOWNLOADING_HASH )
return "DOWNLOADING_HASH";
else if(m_state == DOWNLOADING_FILE )
return "DOWNLOADING_FILE";
else
return "DOWNLOADED";
}
signals:
void receivedChanged(int value);
void statusChanged();
void stateChanged(DownloadState state);
void stateStringChanged();
private slots:
void fileDownloaded(){
// let's check some error
if(m_downloadReply->error() != QNetworkReply::NoError) {
m_state = NETWORK_ERROR;
} else {
if(m_tmp.write(m_downloadReply->readAll()) == -1) return;
if(QFile(m_localPath).exists())
QFile::remove(m_localPath);
m_tmp.close();
computeLocalHash(m_tmp);
if(m_localHash == m_remoteHash) {
if(!m_tmp.rename(m_localPath)) return;
m_tmp.setAutoRemove(false);
m_state = DOWNLOADED;
}
else {
m_state = NETWORK_ERROR;
}
}
emit stateChanged(m_state);
};
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal){
if(m_tmp.write(m_downloadReply->readAll()) == -1) return;
if(!bytesTotal) return;
m_received = bytesReceived*100/bytesTotal;
emit receivedChanged(m_received);
};
void setDownloadUrl(QUrl url);
void computeLocalHash(QFile& file);
void requestHash(QUrl url);
void computeRemoteHash();
void handleStateChange(DownloadState state){
#ifdef QT_WIDGET
switch(state) {
case NETWORK_ERROR:
if(m_localHash == "") {
setLabelText("Network Error");
setCancelButton(new QPushButton("OK"));
show();
} else {
emit finished(0);
}
break;
case DOWNLOADED:
emit finished(0);
break;
case DOWNLOADING_HASH:
break;
case DOWNLOADING_FILE:
show();
break;
}
#else
emit stateStringChanged();
#endif //QT_WIDGET
};
#ifdef QT_WIDGET
void handleCancel(){
QCoreApplication::instance()->exit(1);
}
#endif //QT_WIDGET
private:
DownloadState m_state;
QNetworkAccessManager m_WebCtrl;
qint64 m_received;
QTemporaryFile m_tmp;
QString m_targetFile;
QString m_localPath;
QString m_localHash;
QString m_remoteHash;
bool m_OK;
QString m_status;
QNetworkReply* m_downloadReply;
QNetworkReply* m_hashReply;
};
#ifndef QT_WIDGET
QML_DECLARE_TYPEINFO(FileDownloader, QML_HAS_ATTACHED_PROPERTIES)
#endif //QT_WIDGET
#endif // FILEDOWNLOADER_H