diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index a6feaecd5..e05cf41e8 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -26,6 +26,7 @@ #include "modulesystem/ModuleManager.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" +#include "JobQueue.h" #include "Settings.h" #include "ViewManager.h" @@ -165,5 +166,5 @@ CalamaresApplication::onPluginsReady() void CalamaresApplication::initJobQueue() { - + new Calamares::JobQueue( this ); } diff --git a/src/libcalamares/JobQueue.cpp b/src/libcalamares/JobQueue.cpp index fe4e74423..334914828 100644 --- a/src/libcalamares/JobQueue.cpp +++ b/src/libcalamares/JobQueue.cpp @@ -17,9 +17,55 @@ */ #include "JobQueue.h" + +#include "Job.h" + +#include + namespace Calamares { +class JobThread : public QThread +{ +public: + JobThread( JobQueue* queue ) + : QThread( queue ) + , m_queue( queue ) + { + } + + void setJobs( const QList< Calamares::job_ptr >& jobs ) + { + m_jobs = jobs; + } + + void run() override + { + int total = m_jobs.size(); + int current = 0; + for( auto job : m_jobs ) + { + emitProgress( current, total, job->prettyName() ); + job->exec(); + ++current; + } + emitProgress( total, total, QString() ); + } + +private: + QList< Calamares::job_ptr > m_jobs; + JobQueue* m_queue; + + void emitProgress( int current, int total, const QString& prettyName ) + { + QMetaObject::invokeMethod( m_queue, "progress", Qt::QueuedConnection, + Q_ARG( int, current ), + Q_ARG( int, total ), + Q_ARG( QString, prettyName ) + ); + } +}; + JobQueue* JobQueue::s_instance = nullptr; @@ -33,20 +79,35 @@ JobQueue::instance() JobQueue::JobQueue( QObject* parent ) : QObject( parent ) + , m_thread( new JobThread( this ) ) { + Q_ASSERT( !s_instance ); + s_instance = this; +} + + +void +JobQueue::start() +{ + Q_ASSERT( !m_thread->isRunning() ); + m_thread->setJobs( m_jobs ); + m_thread->start(); } void JobQueue::enqueue( const Calamares::job_ptr& job ) { + Q_ASSERT( !m_thread->isRunning() ); + m_jobs.append( job ); } void JobQueue::enqueue( const QList< job_ptr >& jobs ) { - + Q_ASSERT( !m_thread->isRunning() ); + m_jobs.append( jobs ); } } // namespace Calamares diff --git a/src/libcalamares/JobQueue.h b/src/libcalamares/JobQueue.h index e1145bfbc..014b3d4ce 100644 --- a/src/libcalamares/JobQueue.h +++ b/src/libcalamares/JobQueue.h @@ -27,6 +27,8 @@ namespace Calamares { +class JobThread; + class DLLEXPORT JobQueue : public QObject { Q_OBJECT @@ -37,13 +39,16 @@ public: void enqueue( const Calamares::job_ptr& job ); void enqueue( const QList< Calamares::job_ptr >& jobs ); + void start(); signals: - void jobRunning( const Calamares::job_ptr& ); - void jobFinished( const Calamares::job_ptr& ); + void progress( int current, int total, const QString& prettyName ); private: static JobQueue* s_instance; + + QList< Calamares::job_ptr > m_jobs; + JobThread* m_thread; }; } diff --git a/src/libcalamaresui/InstallationViewStep.cpp b/src/libcalamaresui/InstallationViewStep.cpp index 851218423..4b3035061 100644 --- a/src/libcalamaresui/InstallationViewStep.cpp +++ b/src/libcalamaresui/InstallationViewStep.cpp @@ -18,15 +18,26 @@ #include +#include + #include +#include +#include namespace Calamares { InstallationViewStep::InstallationViewStep( QObject* parent ) : ViewStep( parent ) - , m_widget( new QLabel( "[Installation Progress]" ) ) + , m_widget( new QWidget ) { + m_progressBar = new QProgressBar; + m_label = new QLabel; + QVBoxLayout* layout = new QVBoxLayout( m_widget ); + layout->addWidget(m_progressBar); + layout->addWidget(m_label); + + connect( JobQueue::instance(), &JobQueue::progress, this, &InstallationViewStep::updateFromJobQueue ); } QString @@ -76,4 +87,12 @@ InstallationViewStep::jobs() const return QList< Calamares::job_ptr >(); } +void +InstallationViewStep::updateFromJobQueue( int current, int total, const QString& message ) +{ + m_progressBar->setMaximum( total ); + m_progressBar->setValue( current ); + m_label->setText( message ); +} + } // namespace diff --git a/src/libcalamaresui/InstallationViewStep.h b/src/libcalamaresui/InstallationViewStep.h index 74381b1d1..6cfe52dec 100644 --- a/src/libcalamaresui/InstallationViewStep.h +++ b/src/libcalamaresui/InstallationViewStep.h @@ -21,6 +21,9 @@ #include +class QLabel; +class QProgressBar; + namespace Calamares { @@ -45,6 +48,10 @@ public: private: QWidget* m_widget; + QProgressBar* m_progressBar; + QLabel* m_label; + + void updateFromJobQueue( int current, int total, const QString& message ); }; } diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 6701b68a4..9bdfe08ae 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -20,6 +20,7 @@ #include "viewpages/ViewStep.h" #include "InstallationViewStep.h" +#include "JobQueue.h" #include #include @@ -152,6 +153,10 @@ ViewManager::next() m_steps.at( m_currentStep )->onActivate(); installing = m_steps.at( m_currentStep ) == m_installationViewStep; emit currentStepChanged(); + if ( installing ) + { + startInstallation(); + } } else { @@ -186,4 +191,14 @@ ViewManager::back() m_back->setEnabled( false ); } +void +ViewManager::startInstallation() +{ + for( ViewStep* step : m_prepareSteps ) + { + JobQueue::instance()->enqueue( step->jobs() ); + } + JobQueue::instance()->start(); +} + } diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index 6c47464e7..9b18a1828 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -72,6 +72,7 @@ private: QPushButton* m_quit; void insertViewStep( int before, ViewStep* step ); + void startInstallation(); }; }