diff --git a/src/libcalamaresui/viewpages/QmlViewStep.cpp b/src/libcalamaresui/viewpages/QmlViewStep.cpp index 11637d04b..3cfcc7371 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.cpp +++ b/src/libcalamaresui/viewpages/QmlViewStep.cpp @@ -18,8 +18,14 @@ #include "QmlViewStep.h" +#include "utils/Dirs.h" +#include "utils/Logger.h" #include "widgets/WaitingWidget.h" +#include +#include +#include +#include #include #include @@ -31,9 +37,24 @@ QmlViewStep::QmlViewStep( const QString& name, QObject* parent ) , m_name( name ) , m_widget( new QWidget ) , m_spinner( new WaitingWidget( tr( "Loading ..." ) ) ) + , m_qmlWidget( new QQuickWidget ) { QVBoxLayout* layout = new QVBoxLayout( m_widget ); layout->addWidget( m_spinner ); + + m_qmlWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + m_qmlWidget->setResizeMode( QQuickWidget::SizeRootObjectToView ); + m_qmlWidget->engine()->addImportPath( CalamaresUtils::qmlModulesDir().absolutePath() ); + + // TODO: search for suitable file + QString qrcName = QStringLiteral( ":/%1.qml" ).arg( m_name ); + m_qmlFileName = qrcName; + + cDebug() << "QmlViewStep loading" << m_qmlFileName; + m_qmlComponent = new QQmlComponent( + m_qmlWidget->engine(), QUrl( m_qmlFileName ), QQmlComponent::CompilationMode::Asynchronous ); + connect( m_qmlComponent, &QQmlComponent::statusChanged, this, &QmlViewStep::loadComplete ); + cDebug() << Logger::SubEntry << "Status" << m_qmlComponent->status(); } QmlViewStep::~QmlViewStep() {} @@ -94,3 +115,53 @@ Calamares::QmlViewStep::widget() { return m_widget; } + +void +Calamares::QmlViewStep::loadComplete() +{ + cDebug() << "QML component" << m_qmlFileName << m_qmlComponent->status(); + if ( m_qmlComponent->isReady() && !m_qmlObject ) + { + cDebug() << "QML component complete" << m_qmlFileName; + // Don't do this again + disconnect( m_qmlComponent, &QQmlComponent::statusChanged, this, &QmlViewStep::loadComplete ); + + QObject* o = m_qmlComponent->create(); + m_qmlObject = qobject_cast< QQuickItem* >( o ); + if ( !m_qmlObject ) + { + cError() << Logger::SubEntry << "Could not create QML from" << m_qmlFileName; + delete o; + } + else + { + // setContent() is public API, but not documented publicly. + // It is marked \internal in the Qt sources, but does exactly + // what is needed: sets up visual parent by replacing the root + // item, and handling resizes. + m_qmlWidget->setContent( QUrl( m_qmlFileName ), m_qmlComponent, m_qmlObject ); + showQml(); + } + } +} + +void +Calamares::QmlViewStep::showQml() +{ + if ( !m_qmlWidget || !m_qmlObject ) + { + cDebug() << "showQml() called but no QML object"; + return; + } + if ( m_spinner ) + { + m_widget->layout()->removeWidget( m_spinner ); + m_widget->layout()->addWidget( m_qmlWidget ); + delete m_spinner; + m_spinner = nullptr; + } + else + { + cDebug() << "showQml() called twice"; + } +} diff --git a/src/libcalamaresui/viewpages/QmlViewStep.h b/src/libcalamaresui/viewpages/QmlViewStep.h index d1b28af35..0503f5cde 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.h +++ b/src/libcalamaresui/viewpages/QmlViewStep.h @@ -58,12 +58,19 @@ public: virtual JobList jobs() const override; +private Q_SLOTS: + void loadComplete(); + private: + /// @brief Swap out the spinner for the QQuickWidget + void showQml(); + QString m_name; + QString m_qmlFileName; QWidget* m_widget = nullptr; WaitingWidget* m_spinner = nullptr; - QQuickWidget* m_qmlShow = nullptr; + QQuickWidget* m_qmlWidget = nullptr; QQmlComponent* m_qmlComponent = nullptr; QQuickItem* m_qmlObject = nullptr; };