Connect extract operation to progress calculation.

Ignore senders which are sending 100% more then once, got that from
7z lib at the extracting step.

Task-number: QTIFW-11
Task-number: QTIFW-141

Change-Id: I7750f9e49d5705df91e6c79c7ee2b0530e156e84
Reviewed-by: Karsten Heimrich <karsten.heimrich@digia.com>
Reviewed-by: Tim Jenssen <tim.jenssen@digia.com>
This commit is contained in:
kh1 2013-10-08 16:09:01 +02:00 committed by Tim Jenssen
parent 1d090c2899
commit c8de51cadb
4 changed files with 38 additions and 14 deletions

View File

@ -75,13 +75,12 @@ bool ExtractArchiveOperation::performOperation()
Receiver receiver;
Callback callback;
// usually we have to connect it as queued connection but then some blocking work is in the main thread
connect(&callback, SIGNAL(progressChanged(QString)), this, SLOT(slotProgressChanged(QString)),
Qt::DirectConnection);
connect(&callback, SIGNAL(currentFileChanged(QString)), this, SLOT(fileFinished(QString)));
connect(&callback, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
if (PackageManagerCore *core = this->value(QLatin1String("installer")).value<PackageManagerCore*>()) {
connect(core, SIGNAL(statusChanged(QInstaller::PackageManagerCore::Status)), &callback,
SLOT(statusChanged(QInstaller::PackageManagerCore::Status)), Qt::QueuedConnection);
SLOT(statusChanged(QInstaller::PackageManagerCore::Status)));
}
//Runnable is derived from QRunable which will be deleted by the ThreadPool -> no parent is needed
@ -125,8 +124,8 @@ bool ExtractArchiveOperation::undoOperation()
const QStringList files = value(QLatin1String("files")).toStringList();
WorkerThread *const thread = new WorkerThread(this, files);
connect(thread, SIGNAL(outputTextChanged(QString)), this, SIGNAL(outputTextChanged(QString)),
Qt::QueuedConnection);
connect(thread, SIGNAL(currentFileChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
connect(thread, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
QEventLoop loop;
connect(thread, SIGNAL(finished()), &loop, SLOT(quit()), Qt::QueuedConnection);
@ -149,7 +148,7 @@ Operation *ExtractArchiveOperation::clone() const
/*!
This slot is direct connected to the caller so please don't call it from another thread in the same time.
*/
void ExtractArchiveOperation::slotProgressChanged(const QString &filename)
void ExtractArchiveOperation::fileFinished(const QString &filename)
{
QStringList files = value(QLatin1String("files")).toStringList();
files.prepend(filename);

View File

@ -64,9 +64,10 @@ public:
Q_SIGNALS:
void outputTextChanged(const QString &progress);
void progressChanged(double);
private Q_SLOTS:
void slotProgressChanged(const QString &progress);
void fileFinished(const QString &progress);
private:
class Callback;

View File

@ -71,9 +71,12 @@ public:
ExtractArchiveOperation *const op = m_op;//dynamic_cast< ExtractArchiveOperation* >(parent());
Q_ASSERT(op != 0);
int removedCounter = 0;
foreach (const QString &file, m_files) {
removedCounter++;
const QFileInfo fi(file);
emit outputTextChanged(file);
emit currentFileChanged(file);
emit progressChanged(double(removedCounter) / m_files.count());
if (fi.isFile() || fi.isSymLink()) {
op->deleteFileNowOrLater(fi.absoluteFilePath());
} else if (fi.isDir()) {
@ -85,7 +88,8 @@ public:
}
Q_SIGNALS:
void outputTextChanged(const QString &filename);
void currentFileChanged(const QString &filename);
void progressChanged(double);
private:
QStringList m_files;
@ -105,7 +109,8 @@ public:
Callback() : state(S_OK), createBackups(true) {}
Q_SIGNALS:
void progressChanged(const QString &filename);
void currentFileChanged(const QString &filename);
void progressChanged(double progress);
public Q_SLOTS:
void statusChanged(QInstaller::PackageManagerCore::Status status)
@ -130,7 +135,7 @@ public Q_SLOTS:
protected:
void setCurrentFile(const QString &filename)
{
emit progressChanged(QDir::toNativeSeparators(filename));
emit currentFileChanged(QDir::toNativeSeparators(filename));
}
static QString generateBackupName(const QString &fn)
@ -161,8 +166,9 @@ protected:
return true;
}
HRESULT setCompleted(quint64 /*completed*/, quint64 /*total*/)
HRESULT setCompleted(quint64 completed, quint64 total)
{
emit progressChanged(double(completed) / total);
return state;
}
};

View File

@ -103,6 +103,14 @@ void ProgressCoordinator::registerPartProgress(QObject *sender, const char *sign
Q_ASSERT(isConnected);
}
/*!
This slot gets the progress changed signals from different tasks. The values 0 and 1 are handled as
special values.
0 - is just ignored, so you can use a timer which gives the progress, e.g. like a downloader does.
1 - means the task is finished, even if there comes another 1 from that task, so it will be ignored.
*/
void ProgressCoordinator::partProgressChanged(double fraction)
{
if (fraction < 0 || fraction > 1) {
@ -110,6 +118,16 @@ void ProgressCoordinator::partProgressChanged(double fraction)
return;
}
// no fraction no change
if (fraction == 0)
return;
// ignore senders sending 100% multiple times
if (fraction == 1 && m_senderPendingCalculatedPercentageHash.contains(sender())
&& m_senderPendingCalculatedPercentageHash.value(sender()) == 0) {
return;
}
double partProgressSize = m_senderPartProgressSizeHash.value(sender(), 0);
if (partProgressSize == 0) {
qWarning() << "It seems that this sender was not registered in the right way:" << sender();
@ -176,7 +194,7 @@ void ProgressCoordinator::partProgressChanged(double fraction)
m_currentCompletePercentage = newCurrentCompletePercentage;
if (fraction == 1 || fraction == 0) {
if (fraction == 1) {
m_currentBasePercentage = m_currentBasePercentage + pendingCalculatedPartPercentage;
m_senderPendingCalculatedPercentageHash.insert(sender(), 0);
} else {