diff --git a/src/libcalamares/Job.h b/src/libcalamares/Job.h index af9982e71..85eb93cf4 100644 --- a/src/libcalamares/Job.h +++ b/src/libcalamares/Job.h @@ -64,8 +64,7 @@ public: virtual QString prettyName() const = 0; virtual JobResult exec() = 0; signals: - void running( const Calamares::job_ptr& ); - void finished( const Calamares::job_ptr& ); + void progress( qreal percent ); }; } // namespace Calamares diff --git a/src/libcalamares/JobQueue.cpp b/src/libcalamares/JobQueue.cpp index f6c7d17ed..b91b40897 100644 --- a/src/libcalamares/JobQueue.cpp +++ b/src/libcalamares/JobQueue.cpp @@ -20,6 +20,7 @@ #include "Job.h" #include "GlobalStorage.h" +#include "utils/Logger.h" #include "CalamaresConfig.h" #ifdef WITH_PYTHON @@ -50,12 +51,11 @@ public: void run() override { - qreal total = m_jobs.size(); - int current = 0; + m_jobIndex = 0; for( auto job : m_jobs ) { - qreal percent = current / total; - emitProgress( percent, job->prettyName() ); + emitProgress(); + connect( job.data(), &Job::progress, this, &JobThread::emitProgress ); JobResult result = job->exec(); if ( !result ) { @@ -63,21 +63,34 @@ public: emitFinished(); return; } - ++current; + ++m_jobIndex; } - emitProgress( 1, QString() ); + emitProgress(); emitFinished(); } private: QList< Calamares::job_ptr > m_jobs; JobQueue* m_queue; + int m_jobIndex; - void emitProgress( qreal percent, const QString& prettyName ) + void emitProgress( qreal jobPercent = 0 ) { + // Make sure jobPercent is reasonable, in case a job messed up its + // percentage computations. + jobPercent = qBound( qreal( 0 ), jobPercent, qreal( 1 ) ); + + int jobCount = m_jobs.size(); + QString message = m_jobIndex < jobCount + ? m_jobs.at( m_jobIndex )->prettyName() + : tr( "Done" ); + + qreal percent = ( m_jobIndex + jobPercent ) / qreal( jobCount ); + cLog() << Q_FUNC_INFO << "percent=" << percent * 100 << message; + QMetaObject::invokeMethod( m_queue, "progress", Qt::QueuedConnection, Q_ARG( qreal, percent ), - Q_ARG( QString, prettyName ) + Q_ARG( QString, message ) ); } diff --git a/src/modules/partition/CreatePartitionJob.cpp b/src/modules/partition/CreatePartitionJob.cpp index 02a0950c3..ec94d2b75 100644 --- a/src/modules/partition/CreatePartitionJob.cpp +++ b/src/modules/partition/CreatePartitionJob.cpp @@ -53,9 +53,13 @@ CreatePartitionJob::prettyName() const Calamares::JobResult CreatePartitionJob::exec() { + int step = 0; + const qreal stepCount = 4; + Report report( 0 ); QString message = tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() ); + progress( step++ / stepCount ); CoreBackend* backend = CoreBackendManager::self()->backend(); QScopedPointer backendDevice( backend->openDevice( m_device->deviceNode() ) ); if ( !backendDevice.data() ) @@ -66,6 +70,7 @@ CreatePartitionJob::exec() ); } + progress( step++ / stepCount ); QScopedPointer backendPartitionTable( backendDevice->openPartitionTable() ); if ( !backendPartitionTable.data() ) { @@ -75,6 +80,7 @@ CreatePartitionJob::exec() ); } + progress( step++ / stepCount ); QString partitionPath = backendPartitionTable->createPartition( report, *m_partition ); if ( partitionPath.isEmpty() ) { @@ -85,6 +91,7 @@ CreatePartitionJob::exec() } backendPartitionTable->commit(); + progress( step++ / stepCount ); FileSystem& fs = m_partition->fileSystem(); if ( fs.type() == FileSystem::Unformatted || fs.type() == FileSystem::Extended ) return Calamares::JobResult::ok();