Moved the file copy worker to its own files.

This commit is contained in:
Jonathan Young 2014-05-16 21:33:57 +10:00
parent 48d13fb321
commit fdb1b8144f
9 changed files with 172 additions and 114 deletions

80
filecopy.cpp Normal file
View file

@ -0,0 +1,80 @@
/*
The MIT License (MIT)
Copyright (c) 2013 The ioquake Group
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <QFile>
#include <QFileInfo>
#include "filecopy.h"
FileCopyWorker::FileCopyWorker(const QList<FileCopyOperation> &files) : files(files), isCancelled(false)
{
}
void FileCopyWorker::copy()
{
for (int i = 0; i < files.size(); i++)
{
QFile sourceFile(files.at(i).source);
if (!sourceFile.open(QIODevice::ReadOnly))
{
emit errorMessage(QString("'%1': %2").arg(files.at(i).source).arg(sourceFile.errorString()));
return;
}
QFile destinationFile(files.at(i).dest);
if (!destinationFile.open(QIODevice::WriteOnly))
{
emit errorMessage(QString("'%1': %2").arg(files.at(i).dest).arg(destinationFile.errorString()));
return;
}
emit fileChanged(QFileInfo(sourceFile.fileName()).fileName());
const qint64 totalBytes = sourceFile.size();
qint64 totalBytesWritten = 0;
for (;;)
{
const qint64 bytesRead = sourceFile.read(buffer, bufferSize);
if (bytesRead == 0)
break;
const qint64 bytesWritten = destinationFile.write(buffer, bytesRead);
totalBytesWritten += bytesWritten;
emit progressChanged(totalBytesWritten, totalBytes);
QMutexLocker locker(&cancelMutex);
if (isCancelled)
break;
}
}
emit copyFinished();
}
void FileCopyWorker::cancel()
{
QMutexLocker locker(&cancelMutex);
isCancelled = true;
}

61
filecopy.h Normal file
View file

@ -0,0 +1,61 @@
/*
The MIT License (MIT)
Copyright (c) 2013 The ioquake Group
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef FILECOPY_H
#define FILECOPY_H
#include <QList>
#include <QObject>
#include <QMutex>
struct FileCopyOperation
{
QString source;
QString dest;
};
class FileCopyWorker : public QObject
{
Q_OBJECT
public:
FileCopyWorker(const QList<FileCopyOperation> &files);
void cancel();
public slots:
void copy();
signals:
void fileChanged(const QString &filename);
void progressChanged(qint64 bytesWritten, qint64 bytesTotal);
void errorMessage(const QString &message);
void copyFinished();
private:
static const int bufferSize = 32 * 1024;
const QList<FileCopyOperation> files;
char buffer[bufferSize];
bool isCancelled;
QMutex cancelMutex;
};
#endif // FILECOPY_H

View file

@ -37,22 +37,22 @@ InstallWizard::~InstallWizard()
delete ui; delete ui;
} }
void InstallWizard::clearCopyFiles() void InstallWizard::clearFileCopyOperations()
{ {
copyFiles.clear(); fileCopyOperations.clear();
} }
void InstallWizard::addCopyFile(const QString &source, const QString &dest) void InstallWizard::addFileCopyOperation(const QString &source, const QString &dest)
{ {
CopyFile cf; FileCopyOperation fco;
cf.source = source; fco.source = source;
cf.dest = dest; fco.dest = dest;
copyFiles.append(cf); fileCopyOperations.append(fco);
} }
const QList<InstallWizard::CopyFile> &InstallWizard::getCopyFiles() const const QList<FileCopyOperation> &InstallWizard::getFileCopyOperations() const
{ {
return copyFiles; return fileCopyOperations;
} }
bool InstallWizard::getIsQuake3PatchRequired() const bool InstallWizard::getIsQuake3PatchRequired() const

View file

@ -2,6 +2,7 @@
#define INSTALLWIZARD_H #define INSTALLWIZARD_H
#include <QWizard> #include <QWizard>
#include "filecopy.h"
namespace Ui { namespace Ui {
class InstallWizard; class InstallWizard;
@ -18,15 +19,9 @@ public:
explicit InstallWizard(QWidget *parent, Settings *settings); explicit InstallWizard(QWidget *parent, Settings *settings);
~InstallWizard(); ~InstallWizard();
struct CopyFile void clearFileCopyOperations();
{ void addFileCopyOperation(const QString &source, const QString &dest);
QString source; const QList<FileCopyOperation> &getFileCopyOperations() const;
QString dest;
};
void clearCopyFiles();
void addCopyFile(const QString &source, const QString &dest);
const QList<CopyFile> &getCopyFiles() const;
bool getIsQuake3PatchRequired() const; bool getIsQuake3PatchRequired() const;
void setIsQuake3PatchRequired(bool value); void setIsQuake3PatchRequired(bool value);
@ -51,7 +46,7 @@ private:
Ui::InstallWizard *ui; Ui::InstallWizard *ui;
QPushButton *cancelButton; QPushButton *cancelButton;
Settings *settings; Settings *settings;
QList<CopyFile> copyFiles; QList<FileCopyOperation> fileCopyOperations;
bool isQuake3PatchRequired; bool isQuake3PatchRequired;
QString quakePath; QString quakePath;
}; };

View file

@ -4,61 +4,6 @@
#include "installwizard_copy.h" #include "installwizard_copy.h"
#include "ui_installwizard_copy.h" #include "ui_installwizard_copy.h"
CopyWorker::CopyWorker(const QList<InstallWizard::CopyFile> &copyFiles) : copyFiles(copyFiles), isCancelled(false)
{
}
void CopyWorker::copy()
{
for (int i = 0; i < copyFiles.size(); i++)
{
QFile sourceFile(copyFiles.at(i).source);
if (!sourceFile.open(QIODevice::ReadOnly))
{
emit errorMessage(QString("'%1': %2").arg(copyFiles.at(i).source).arg(sourceFile.errorString()));
return;
}
QFile destinationFile(copyFiles.at(i).dest);
if (!destinationFile.open(QIODevice::WriteOnly))
{
emit errorMessage(QString("'%1': %2").arg(copyFiles.at(i).dest).arg(destinationFile.errorString()));
return;
}
emit fileChanged(QFileInfo(sourceFile.fileName()).fileName());
const qint64 totalBytes = sourceFile.size();
qint64 totalBytesWritten = 0;
for (;;)
{
const qint64 bytesRead = sourceFile.read(buffer, bufferSize);
if (bytesRead == 0)
break;
const qint64 bytesWritten = destinationFile.write(buffer, bytesRead);
totalBytesWritten += bytesWritten;
emit progressChanged(totalBytesWritten, totalBytes);
QMutexLocker locker(&cancelMutex);
if (isCancelled)
break;
}
}
emit copyFinished();
}
void CopyWorker::cancel()
{
QMutexLocker locker(&cancelMutex);
isCancelled = true;
}
InstallWizard_Copy::InstallWizard_Copy(QWidget *parent) : InstallWizard_Copy::InstallWizard_Copy(QWidget *parent) :
QWizardPage(parent), QWizardPage(parent),
ui(new Ui::InstallWizard_Copy), ui(new Ui::InstallWizard_Copy),
@ -92,14 +37,14 @@ void InstallWizard_Copy::initializePage()
} }
// Start copy thread. // Start copy thread.
copyWorker = new CopyWorker(((InstallWizard *)wizard())->getCopyFiles()); copyWorker = new FileCopyWorker(((InstallWizard *)wizard())->getFileCopyOperations());
copyWorker->moveToThread(&copyThread); copyWorker->moveToThread(&copyThread);
connect(&copyThread, &QThread::finished, copyWorker, &QObject::deleteLater); connect(&copyThread, &QThread::finished, copyWorker, &QObject::deleteLater);
connect(this, &InstallWizard_Copy::copy, copyWorker, &CopyWorker::copy); connect(this, &InstallWizard_Copy::copy, copyWorker, &FileCopyWorker::copy);
connect(copyWorker, &CopyWorker::fileChanged, this, &InstallWizard_Copy::setCopyFilename); connect(copyWorker, &FileCopyWorker::fileChanged, this, &InstallWizard_Copy::setCopyFilename);
connect(copyWorker, &CopyWorker::progressChanged, this, &InstallWizard_Copy::setCopyProgress); connect(copyWorker, &FileCopyWorker::progressChanged, this, &InstallWizard_Copy::setCopyProgress);
connect(copyWorker, &CopyWorker::errorMessage, this, &InstallWizard_Copy::setCopyErrorMessage); connect(copyWorker, &FileCopyWorker::errorMessage, this, &InstallWizard_Copy::setCopyErrorMessage);
connect(copyWorker, &CopyWorker::copyFinished, this, &InstallWizard_Copy::finishCopy); connect(copyWorker, &FileCopyWorker::copyFinished, this, &InstallWizard_Copy::finishCopy);
copyThread.start(); copyThread.start();
emit copy(); emit copy();

View file

@ -1,39 +1,14 @@
#ifndef INSTALLWIZARD_COPY_H #ifndef INSTALLWIZARD_COPY_H
#define INSTALLWIZARD_COPY_H #define INSTALLWIZARD_COPY_H
#include <QMutex>
#include <QThread> #include <QThread>
#include <QWizardPage>
#include "installwizard.h" #include "installwizard.h"
namespace Ui { namespace Ui {
class InstallWizard_Copy; class InstallWizard_Copy;
} }
class CopyWorker : public QObject class FileCopyWorker;
{
Q_OBJECT
public:
CopyWorker(const QList<InstallWizard::CopyFile> &copyFiles);
void cancel();
public slots:
void copy();
signals:
void fileChanged(const QString &filename);
void progressChanged(qint64 bytesWritten, qint64 bytesTotal);
void errorMessage(const QString &message);
void copyFinished();
private:
static const int bufferSize = 32 * 1024;
const QList<InstallWizard::CopyFile> copyFiles;
char buffer[bufferSize];
bool isCancelled;
QMutex cancelMutex;
};
class InstallWizard_Copy : public QWizardPage class InstallWizard_Copy : public QWizardPage
{ {
@ -58,7 +33,7 @@ signals:
private: private:
Ui::InstallWizard_Copy *ui; Ui::InstallWizard_Copy *ui;
CopyWorker *copyWorker; FileCopyWorker *copyWorker;
QThread copyThread; QThread copyThread;
bool isCopyFinished; bool isCopyFinished;

View file

@ -16,7 +16,7 @@ InstallWizard_Eula::~InstallWizard_Eula()
int InstallWizard_Eula::nextId() const int InstallWizard_Eula::nextId() const
{ {
if (!((InstallWizard *)wizard())->getCopyFiles().isEmpty()) if (!((InstallWizard *)wizard())->getFileCopyOperations().isEmpty())
{ {
return InstallWizard::Page_Copy; return InstallWizard::Page_Copy;
} }

View file

@ -72,8 +72,8 @@ bool InstallWizard_Setup::validatePage()
iw->setIsQuake3PatchRequired(true); iw->setIsQuake3PatchRequired(true);
// Copy page will copy baseq3/pak0.pk3. // Copy page will copy baseq3/pak0.pk3.
iw->clearCopyFiles(); iw->clearFileCopyOperations();
iw->addCopyFile(ui->cbInstallSource->currentText() + QString("/QUAKE3/baseq3/pak0.pk3"), ui->txtInstallDest->text() + QString("/baseq3/pak0.pk3")); iw->addFileCopyOperation(ui->cbInstallSource->currentText() + QString("/QUAKE3/baseq3/pak0.pk3"), ui->txtInstallDest->text() + QString("/baseq3/pak0.pk3"));
iw->setQuakePath(ui->txtInstallDest->text()); iw->setQuakePath(ui->txtInstallDest->text());
} }
else if (ui->stackPages->currentIndex() == Page_InstallSteam) else if (ui->stackPages->currentIndex() == Page_InstallSteam)
@ -98,11 +98,11 @@ bool InstallWizard_Setup::validatePage()
// Copy page will copy baseq3/*.pk3 files. // Copy page will copy baseq3/*.pk3 files.
QFileInfoList pakFiles = steamQuakeDir.entryInfoList(QStringList("*.pk3"), QDir::Files | QDir::NoSymLinks | QDir::Readable, QDir::Name); QFileInfoList pakFiles = steamQuakeDir.entryInfoList(QStringList("*.pk3"), QDir::Files | QDir::NoSymLinks | QDir::Readable, QDir::Name);
iw->clearCopyFiles(); iw->clearFileCopyOperations();
for (int i = 0; i < pakFiles.size(); i++) for (int i = 0; i < pakFiles.size(); i++)
{ {
iw->addCopyFile(pakFiles.at(i).absoluteFilePath(), ui->txtInstallSteamDest->text() + QString("/baseq3/") + pakFiles.at(i).fileName()); iw->addFileCopyOperation(pakFiles.at(i).absoluteFilePath(), ui->txtInstallSteamDest->text() + QString("/baseq3/") + pakFiles.at(i).fileName());
} }
iw->setQuakePath(ui->txtInstallSteamDest->text()); iw->setQuakePath(ui->txtInstallSteamDest->text());

View file

@ -20,7 +20,8 @@ SOURCES += main.cpp\
installwizard_finished.cpp \ installwizard_finished.cpp \
installwizard_patch.cpp \ installwizard_patch.cpp \
installwizard_eula.cpp \ installwizard_eula.cpp \
installwizard_copy.cpp installwizard_copy.cpp \
filecopy.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
settings.h \ settings.h \
@ -29,7 +30,8 @@ HEADERS += mainwindow.h \
installwizard_finished.h \ installwizard_finished.h \
installwizard_patch.h \ installwizard_patch.h \
installwizard_eula.h \ installwizard_eula.h \
installwizard_copy.h installwizard_copy.h \
filecopy.h
FORMS += mainwindow.ui \ FORMS += mainwindow.ui \
installwizard.ui \ installwizard.ui \