diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp index 48c5db2c..3897de4e 100644 --- a/src/libs/installer/extractarchiveoperation.cpp +++ b/src/libs/installer/extractarchiveoperation.cpp @@ -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()) { 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); diff --git a/src/libs/installer/extractarchiveoperation.h b/src/libs/installer/extractarchiveoperation.h index 818672fd..53df81e7 100644 --- a/src/libs/installer/extractarchiveoperation.h +++ b/src/libs/installer/extractarchiveoperation.h @@ -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; diff --git a/src/libs/installer/extractarchiveoperation_p.h b/src/libs/installer/extractarchiveoperation_p.h index 4e063283..c7284d9c 100644 --- a/src/libs/installer/extractarchiveoperation_p.h +++ b/src/libs/installer/extractarchiveoperation_p.h @@ -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; } }; diff --git a/src/libs/installer/progresscoordinator.cpp b/src/libs/installer/progresscoordinator.cpp index 7ba2b091..e55f4b8b 100644 --- a/src/libs/installer/progresscoordinator.cpp +++ b/src/libs/installer/progresscoordinator.cpp @@ -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 {