From 526716556c45a02eb0f7b06d688be4dbb79c57c2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 7 May 2020 19:02:38 +0200 Subject: [PATCH 01/38] [libcalamaresui] Store the slideshow-from-images data - This code has existed for a long time but never stored anything to the Branding object, and the most literal slideshow (just some images) was not implemented. --- src/libcalamaresui/Branding.cpp | 2 +- src/libcalamaresui/Branding.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index ae8f3910f..86aa04251 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -238,7 +238,7 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) slideShowPictures[ i ] = imageFi.absoluteFilePath(); } - //FIXME: implement a GenericSlideShow.qml that uses these slideShowPictures + m_slideshowFilenames = slideShowPictures; } else if ( doc[ "slideshow" ].IsScalar() ) { diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index ce694a644..79e2542f1 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -237,6 +237,16 @@ private: QMap< QString, QString > m_strings; QMap< QString, QString > m_images; QMap< QString, QString > m_style; + + /* The slideshow can be done in one of two ways: + * - as a sequence of images + * - as a QML file + * The slideshow: setting selects which one is used. If it is + * a list (of filenames) then it is a sequence of images, and otherwise + * it is a QML file which is run. (For QML, the slideshow API is + * important). + */ + QStringList m_slideshowFilenames; QString m_slideshowPath; int m_slideshowAPI; QString m_translationsPathPrefix; From bb2b5fd982bb831373370594996b29e092fdd486 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 7 May 2020 20:41:40 +0200 Subject: [PATCH 02/38] [libcalamaresui] No reason for bail() to be a method --- src/libcalamaresui/Branding.cpp | 33 ++++++++++++++++++--------------- src/libcalamaresui/Branding.h | 2 -- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 86aa04251..87cfda080 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -41,6 +41,13 @@ #include #endif +[[noreturn]] static void +bail( const QString& descriptorPath, const QString& message ) +{ + cError() << "FATAL in" << descriptorPath << Logger::Continuation << Logger::NoQuote {} << message; + ::exit( EXIT_FAILURE ); +} + namespace Calamares { @@ -153,7 +160,7 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) QDir componentDir( componentDirectory() ); if ( !componentDir.exists() ) { - bail( "Bad component directory path." ); + bail( m_descriptorPath, "Bad component directory path." ); } QFile file( brandingFilePath ); @@ -168,7 +175,8 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) m_componentName = QString::fromStdString( doc[ "componentName" ].as< std::string >() ); if ( m_componentName != componentDir.dirName() ) - bail( "The branding component name should match the name of the " + bail( m_descriptorPath, + "The branding component name should match the name of the " "component directory." ); initSimpleSettings( doc ); @@ -214,7 +222,8 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) // Not found, bail out with the filename used if ( icon.isNull() ) { - bail( QString( "Image file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) ); + bail( m_descriptorPath, + QString( "Image file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) ); } return imageName; // Not turned into a path } @@ -232,7 +241,8 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) ); if ( !imageFi.exists() ) { - bail( QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) ); + bail( m_descriptorPath, + QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) ); } slideShowPictures[ i ] = imageFi.absoluteFilePath(); @@ -245,13 +255,14 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) QString slideshowPath = QString::fromStdString( doc[ "slideshow" ].as< std::string >() ); QFileInfo slideshowFi( componentDir.absoluteFilePath( slideshowPath ) ); if ( !slideshowFi.exists() || !slideshowFi.fileName().toLower().endsWith( ".qml" ) ) - bail( QString( "Slideshow file %1 does not exist or is not a valid QML file." ) + bail( m_descriptorPath, + QString( "Slideshow file %1 does not exist or is not a valid QML file." ) .arg( slideshowFi.absoluteFilePath() ) ); m_slideshowPath = slideshowFi.absoluteFilePath(); } else { - bail( "Syntax error in slideshow sequence." ); + bail( m_descriptorPath, "Syntax error in slideshow sequence." ); } int api = doc[ "slideshowAPI" ].IsScalar() ? doc[ "slideshowAPI" ].as< int >() : -1; @@ -265,7 +276,7 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) catch ( YAML::Exception& e ) { CalamaresUtils::explainYamlException( e, ba, file.fileName() ); - bail( e.what() ); + bail( m_descriptorPath, e.what() ); } QDir translationsDir( componentDir.filePath( "lang" ) ); @@ -540,12 +551,4 @@ Branding::initSimpleSettings( const YAML::Node& doc ) } } - -[[noreturn]] void -Branding::bail( const QString& message ) -{ - cError() << "FATAL in" << m_descriptorPath << Logger::Continuation << Logger::NoQuote {} << message; - ::exit( EXIT_FAILURE ); -} - } // namespace Calamares diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 79e2542f1..87cb9fffa 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -230,8 +230,6 @@ private: static const QStringList s_imageEntryStrings; static const QStringList s_styleEntryStrings; - [[noreturn]] void bail( const QString& message ); - QString m_descriptorPath; // Path to descriptor (e.g. "/etc/calamares/default/branding.desc") QString m_componentName; // Matches last part of full path to containing directory QMap< QString, QString > m_strings; From df1f9f1b568235773a3f54f03b4734a934de3326 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 9 May 2020 23:07:56 +0200 Subject: [PATCH 03/38] [libcalamaresui] Prep-work for image-slideshow Doesn't compile (but I need to get it off this machine) - Prepare to implement a picture-based slideshow alongside QML - Split QML loading into the slideshow component This might be good prep-work for moving QML loading out of the QMLViewStep as well. --- .../viewpages/ExecutionViewStep.cpp | 20 ++---- .../viewpages/ExecutionViewStep.h | 9 +-- src/libcalamaresui/viewpages/Slideshow.cpp | 55 ++++++++++++++++ src/libcalamaresui/viewpages/Slideshow.h | 66 +++++++++++++++++++ 4 files changed, 128 insertions(+), 22 deletions(-) create mode 100644 src/libcalamaresui/viewpages/Slideshow.cpp create mode 100644 src/libcalamaresui/viewpages/Slideshow.h diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp index c9bc4b8c3..e794d6dd4 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp @@ -20,6 +20,8 @@ #include "ExecutionViewStep.h" +#include "Slideshow.h" + #include "Branding.h" #include "Job.h" #include "JobQueue.h" @@ -37,10 +39,6 @@ #include #include #include -#include -#include -#include -#include #include namespace Calamares @@ -51,20 +49,14 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) , m_widget( new QWidget ) , m_progressBar( new QProgressBar ) , m_label( new QLabel ) - , m_qmlShow( new QQuickWidget ) - , m_qmlComponent( nullptr ) - , m_qmlObject( nullptr ) + , m_slideshow( nullptr ) { QVBoxLayout* layout = new QVBoxLayout( m_widget ); QVBoxLayout* innerLayout = new QVBoxLayout; m_progressBar->setMaximum( 10000 ); - m_qmlShow->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); - m_qmlShow->setResizeMode( QQuickWidget::SizeRootObjectToView ); - m_qmlShow->engine()->addImportPath( CalamaresUtils::qmlModulesDir().absolutePath() ); - - layout->addWidget( m_qmlShow ); + layout->addWidget( m_slideshow->widget() ); CalamaresUtils::unmarginLayout( layout ); layout->addLayout( innerLayout ); @@ -72,7 +64,6 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) innerLayout->addWidget( m_progressBar ); innerLayout->addWidget( m_label ); - cDebug() << "QML import paths:" << Logger::DebugList( m_qmlShow->engine()->importPathList() ); if ( Branding::instance()->slideshowAPI() == 2 ) { cDebug() << "QML load on startup, API 2."; @@ -80,9 +71,6 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) } connect( JobQueue::instance(), &JobQueue::progress, this, &ExecutionViewStep::updateFromJobQueue ); -#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 ) - CALAMARES_RETRANSLATE( m_qmlShow->engine()->retranslate(); ) -#endif } diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.h b/src/libcalamaresui/viewpages/ExecutionViewStep.h index e797c3cb2..340f96745 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.h +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.h @@ -27,13 +27,12 @@ class QLabel; class QObject; class QProgressBar; -class QQmlComponent; -class QQuickItem; -class QQuickWidget; namespace Calamares { +class Slideshow; + class ExecutionViewStep : public ViewStep { Q_OBJECT @@ -67,9 +66,7 @@ private: QWidget* m_widget; QProgressBar* m_progressBar; QLabel* m_label; - QQuickWidget* m_qmlShow; - QQmlComponent* m_qmlComponent; - QQuickItem* m_qmlObject; ///< The actual show + Slideshow* m_slideshow; QStringList m_jobInstanceKeys; diff --git a/src/libcalamaresui/viewpages/Slideshow.cpp b/src/libcalamaresui/viewpages/Slideshow.cpp new file mode 100644 index 000000000..f0069cd9d --- /dev/null +++ b/src/libcalamaresui/viewpages/Slideshow.cpp @@ -0,0 +1,55 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Aurélien Gâteau + * Copyright 2014-2015, Teo Mrnjavac + * Copyright 2018, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#include "Slideshow.h" + +#include "utils/Dirs.h" +#include "utils/Logger.h" + +#include +#include +#include +#include + +namespace Calamares +{ + +Slideshow::~Slideshow() +{ +} + +SlideshowQML::SlideshowQML(QWidget* parent) + : Slideshow( parent ) + , m_qmlShow( new QQuickWidget ) + , m_qmlComponent( nullptr ) + , m_qmlObject( nullptr ) +{ + m_qmlShow->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + m_qmlShow->setResizeMode( QQuickWidget::SizeRootObjectToView ); + m_qmlShow->engine()->addImportPath( CalamaresUtils::qmlModulesDir().absolutePath() ); + + cDebug() << "QML import paths:" << Logger::DebugList( m_qmlShow->engine()->importPathList() ); +#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 ) + CALAMARES_RETRANSLATE( m_qmlShow->engine()->retranslate(); ) +#endif + +} + +} diff --git a/src/libcalamaresui/viewpages/Slideshow.h b/src/libcalamaresui/viewpages/Slideshow.h new file mode 100644 index 000000000..5f3612f7e --- /dev/null +++ b/src/libcalamaresui/viewpages/Slideshow.h @@ -0,0 +1,66 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Aurélien Gâteau + * Copyright 2014-2015, Teo Mrnjavac + * Copyright 2018, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#ifndef LIBCALAMARESUI_SLIDESHOW_H +#define LIBCALAMARESUI_SLIDESHOW_H + +#include + +class QQmlComponent; +class QQuickItem; +class QQuickWidget; + +namespace Calamares +{ + +class Slideshow +{ +public: + Slideshow( QWidget* parent ) {}; + virtual ~Slideshow(); + + virtual QWidget* widget() = 0; +}; + +class SlideshowQML : public Slideshow +{ +public: + SlideshowQML( QWidget* parent ); + virtual ~SlideshowQML(); + + QWidget* widget() override; + +private: + QQuickWidget* m_qmlShow; + QQmlComponent* m_qmlComponent; + QQuickItem* m_qmlObject; ///< The actual show +}; + +class SlideshowPictures : public Slideshow +{ +public: + SlideshowPictures( QWidget* parent ); + virtual ~SlideshowPictures(); + + QWidget* widget() override; +}; + +} +#endif From e7f4479df150efa21a3c225916ee5d6580b17064 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 13 May 2020 14:01:51 +0200 Subject: [PATCH 04/38] [libcalamaresui] Move all the slideshow code out of ExecutionViewStep - The SlideshowQML now handles all the bits that were in the viewstep. - The viewstep uses the abstract Slideshow API. --- src/libcalamaresui/CMakeLists.txt | 1 + .../viewpages/ExecutionViewStep.cpp | 116 +--------------- .../viewpages/ExecutionViewStep.h | 4 - src/libcalamaresui/viewpages/Slideshow.cpp | 126 +++++++++++++++++- src/libcalamaresui/viewpages/Slideshow.h | 47 ++++++- 5 files changed, 166 insertions(+), 128 deletions(-) diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index e813b0009..ee7992710 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -19,6 +19,7 @@ set( calamaresui_SOURCES viewpages/BlankViewStep.cpp viewpages/ExecutionViewStep.cpp viewpages/QmlViewStep.cpp + viewpages/Slideshow.cpp viewpages/ViewStep.cpp widgets/ClickableLabel.cpp diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp index e794d6dd4..db73d16b1 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp @@ -49,7 +49,7 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) , m_widget( new QWidget ) , m_progressBar( new QProgressBar ) , m_label( new QLabel ) - , m_slideshow( nullptr ) + , m_slideshow( new SlideshowQML( m_widget ) ) { QVBoxLayout* layout = new QVBoxLayout( m_widget ); QVBoxLayout* innerLayout = new QVBoxLayout; @@ -64,12 +64,6 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) innerLayout->addWidget( m_progressBar ); innerLayout->addWidget( m_label ); - if ( Branding::instance()->slideshowAPI() == 2 ) - { - cDebug() << "QML load on startup, API 2."; - loadQmlV2(); - } - connect( JobQueue::instance(), &JobQueue::progress, this, &ExecutionViewStep::updateFromJobQueue ); } @@ -127,108 +121,10 @@ ExecutionViewStep::isAtEnd() const return !JobQueue::instance()->isRunning(); } -void -ExecutionViewStep::loadQmlV2() -{ - if ( !m_qmlComponent && !Calamares::Branding::instance()->slideshowPath().isEmpty() ) - { - m_qmlComponent = new QQmlComponent( m_qmlShow->engine(), - QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ), - QQmlComponent::CompilationMode::Asynchronous ); - connect( m_qmlComponent, &QQmlComponent::statusChanged, this, &ExecutionViewStep::loadQmlV2Complete ); - } -} - -/// @brief State-change of the slideshow, for changeSlideShowState() -enum class Slideshow -{ - Start, - Stop -}; - -/** @brief Tells the slideshow we activated or left the show. - * - * If @p state is @c Slideshow::Start, calls suitable activation procedures. - * If @p state is @c Slideshow::Stop, calls deactivation procedures. - * - * Applies V1 and V2 QML activation / deactivation: - * - V1 loads the QML in @p widget on activation. Sets root object property - * *activatedInCalamares* as appropriate. - * - V2 calls onActivate() or onLeave() in the QML as appropriate. Also - * sets the *activatedInCalamares* property. - */ -static void -changeSlideShowState( Slideshow state, QQuickItem* slideshow, QQuickWidget* widget ) -{ - bool activate = state == Slideshow::Start; - - if ( Branding::instance()->slideshowAPI() == 2 ) - { - // The QML was already loaded in the constructor, need to start it - CalamaresUtils::callQMLFunction( slideshow, activate ? "onActivate" : "onLeave" ); - } - else if ( !Calamares::Branding::instance()->slideshowPath().isEmpty() ) - { - // API version 1 assumes onCompleted is the trigger - if ( activate ) - { - widget->setSource( QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ) ); - } - // needs the root object for property setting, below - slideshow = widget->rootObject(); - } - - // V1 API has picked up the root object for use, V2 passed it in. - if ( slideshow ) - { - static const char propertyName[] = "activatedInCalamares"; - auto property = slideshow->property( propertyName ); - if ( property.isValid() && ( property.type() == QVariant::Bool ) && ( property.toBool() != activate ) ) - { - slideshow->setProperty( propertyName, activate ); - } - } -} - -void -ExecutionViewStep::loadQmlV2Complete() -{ - if ( m_qmlComponent && m_qmlComponent->isReady() && !m_qmlObject ) - { - cDebug() << "QML component complete, API 2"; - // Don't do this again - disconnect( m_qmlComponent, &QQmlComponent::statusChanged, this, &ExecutionViewStep::loadQmlV2Complete ); - - QObject* o = m_qmlComponent->create(); - m_qmlObject = qobject_cast< QQuickItem* >( o ); - if ( !m_qmlObject ) - { - delete o; - } - else - { - cDebug() << Logger::SubEntry << "Loading" << Calamares::Branding::instance()->slideshowPath(); - - // 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_qmlShow->setContent( - QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ), m_qmlComponent, m_qmlObject ); - if ( ViewManager::instance()->currentStep() == this ) - { - // We're alreay visible! Must have been slow QML loading, and we - // passed onActivate already. - changeSlideShowState( Slideshow::Start, m_qmlObject, m_qmlShow ); - } - } - } -} - void ExecutionViewStep::onActivate() { - changeSlideShowState( Slideshow::Start, m_qmlObject, m_qmlShow ); + m_slideshow->changeSlideShowState( Slideshow::Start ); JobQueue* queue = JobQueue::instance(); foreach ( const QString& instanceKey, m_jobInstanceKeys ) @@ -276,13 +172,7 @@ ExecutionViewStep::updateFromJobQueue( qreal percent, const QString& message ) void ExecutionViewStep::onLeave() { - changeSlideShowState( Slideshow::Stop, m_qmlObject, m_qmlShow ); - // API version 2 is explicitly stopped; version 1 keeps running - if ( Branding::instance()->slideshowAPI() == 2 ) - { - delete m_qmlObject; - m_qmlObject = nullptr; - } + m_slideshow->changeSlideShowState( Slideshow::Stop ); } } // namespace Calamares diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.h b/src/libcalamaresui/viewpages/ExecutionViewStep.h index 340f96745..48604fe93 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.h +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.h @@ -59,9 +59,6 @@ public: void appendJobModuleInstanceKey( const QString& instanceKey ); -public slots: - void loadQmlV2Complete(); - private: QWidget* m_widget; QProgressBar* m_progressBar; @@ -70,7 +67,6 @@ private: QStringList m_jobInstanceKeys; - void loadQmlV2(); ///< Loads the slideshow QML (from branding) for API version 2 void updateFromJobQueue( qreal percent, const QString& message ); }; diff --git a/src/libcalamaresui/viewpages/Slideshow.cpp b/src/libcalamaresui/viewpages/Slideshow.cpp index f0069cd9d..5b264a5dd 100644 --- a/src/libcalamaresui/viewpages/Slideshow.cpp +++ b/src/libcalamaresui/viewpages/Slideshow.cpp @@ -20,22 +20,24 @@ #include "Slideshow.h" +#include "Branding.h" #include "utils/Dirs.h" #include "utils/Logger.h" +#include "utils/Qml.h" +#include "utils/Retranslator.h" -#include +#include #include #include #include +#include namespace Calamares { -Slideshow::~Slideshow() -{ -} +Slideshow::~Slideshow() {} -SlideshowQML::SlideshowQML(QWidget* parent) +SlideshowQML::SlideshowQML( QWidget* parent ) : Slideshow( parent ) , m_qmlShow( new QQuickWidget ) , m_qmlComponent( nullptr ) @@ -47,9 +49,121 @@ SlideshowQML::SlideshowQML(QWidget* parent) cDebug() << "QML import paths:" << Logger::DebugList( m_qmlShow->engine()->importPathList() ); #if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 ) - CALAMARES_RETRANSLATE( m_qmlShow->engine()->retranslate(); ) + CALAMARES_RETRANSLATE( if ( m_qmlShow ) { m_qmlShow->engine()->retranslate(); } ) #endif + if ( Branding::instance()->slideshowAPI() == 2 ) + { + cDebug() << "QML load on startup, API 2."; + loadQmlV2(); + } } +SlideshowQML::~SlideshowQML() +{ } + +QWidget * SlideshowQML::widget() +{ + return m_qmlShow; +} + +void +SlideshowQML::loadQmlV2() +{ + QMutexLocker l( &m_mutex ); + if ( !m_qmlComponent && !Calamares::Branding::instance()->slideshowPath().isEmpty() ) + { + m_qmlComponent = new QQmlComponent( m_qmlShow->engine(), + QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ), + QQmlComponent::CompilationMode::Asynchronous ); + connect( m_qmlComponent, &QQmlComponent::statusChanged, this, &SlideshowQML::loadQmlV2Complete ); + } +} + +void +SlideshowQML::loadQmlV2Complete() +{ + QMutexLocker l( &m_mutex ); + if ( m_qmlComponent && m_qmlComponent->isReady() && !m_qmlObject ) + { + cDebug() << "QML component complete, API 2"; + // Don't do this again + disconnect( m_qmlComponent, &QQmlComponent::statusChanged, this, &SlideshowQML::loadQmlV2Complete ); + + QObject* o = m_qmlComponent->create(); + m_qmlObject = qobject_cast< QQuickItem* >( o ); + if ( !m_qmlObject ) + { + delete o; + } + else + { + cDebug() << Logger::SubEntry << "Loading" << Calamares::Branding::instance()->slideshowPath(); + + // 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_qmlShow->setContent( + QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ), m_qmlComponent, m_qmlObject ); + if ( isActive() ) + { + // We're alreay visible! Must have been slow QML loading, and we + // passed onActivate already. + changeSlideShowState( Slideshow::Start ); + } + } + } +} + +/* + * Applies V1 and V2 QML activation / deactivation: + * - V1 loads the QML in @p widget on activation. Sets root object property + * *activatedInCalamares* as appropriate. + * - V2 calls onActivate() or onLeave() in the QML as appropriate. Also + * sets the *activatedInCalamares* property. + */ +void +SlideshowQML::changeSlideShowState( Action state ) +{ + QMutexLocker l( &m_mutex ); + bool activate = state == Slideshow::Start; + + if ( Branding::instance()->slideshowAPI() == 2 ) + { + // The QML was already loaded in the constructor, need to start it + CalamaresUtils::callQMLFunction( m_qmlObject, activate ? "onActivate" : "onLeave" ); + } + else if ( !Calamares::Branding::instance()->slideshowPath().isEmpty() ) + { + // API version 1 assumes onCompleted is the trigger + if ( activate ) + { + m_qmlShow->setSource( QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ) ); + } + // needs the root object for property setting, below + m_qmlObject = m_qmlShow->rootObject(); + } + + // V1 API has picked up the root object for use, V2 passed it in. + if ( m_qmlObject ) + { + static const char propertyName[] = "activatedInCalamares"; + auto property = m_qmlObject->property( propertyName ); + if ( property.isValid() && ( property.type() == QVariant::Bool ) && ( property.toBool() != activate ) ) + { + m_qmlObject->setProperty( propertyName, activate ); + } + } + + if ( ( Branding::instance()->slideshowAPI() == 2 ) && ( state == Slideshow::Stop ) ) + { + delete m_qmlObject; + m_qmlObject = nullptr; + } + + m_state = state; +} + +} // namespace diff --git a/src/libcalamaresui/viewpages/Slideshow.h b/src/libcalamaresui/viewpages/Slideshow.h index 5f3612f7e..428422db5 100644 --- a/src/libcalamaresui/viewpages/Slideshow.h +++ b/src/libcalamaresui/viewpages/Slideshow.h @@ -21,6 +21,7 @@ #ifndef LIBCALAMARESUI_SLIDESHOW_H #define LIBCALAMARESUI_SLIDESHOW_H +#include #include class QQmlComponent; @@ -30,22 +31,58 @@ class QQuickWidget; namespace Calamares { -class Slideshow +class Slideshow : public QObject { + Q_OBJECT public: - Slideshow( QWidget* parent ) {}; + /// @brief State-change of the slideshow, for changeSlideShowState() + enum Action + { + Start, + Stop + }; + + Slideshow( QWidget* parent = nullptr ) + : QObject( parent ) + { + } virtual ~Slideshow(); + ///@brief Is the slideshow being shown **right now**? + bool isActive() const { return m_state == Start; } + + /** @brief The actual widget to show the user. + * + * Depending on the style of slideshow, this might be a QQuickWidget, + * or a QLabel, or something else entirely. + */ virtual QWidget* widget() = 0; + + /** @brief Tells the slideshow we activated or left the show. + * + * If @p state is @c Slideshow::Start, calls suitable activation procedures. + * If @p state is @c Slideshow::Stop, calls deactivation procedures. + */ + virtual void changeSlideShowState( Action a ) = 0; + +protected: + QMutex m_mutex; + Action m_state = Stop; }; class SlideshowQML : public Slideshow { + Q_OBJECT public: SlideshowQML( QWidget* parent ); - virtual ~SlideshowQML(); + virtual ~SlideshowQML() override; QWidget* widget() override; + void changeSlideShowState( Action a ) override; + +public slots: + void loadQmlV2Complete(); + void loadQmlV2(); ///< Loads the slideshow QML (from branding) for API version 2 private: QQuickWidget* m_qmlShow; @@ -57,10 +94,10 @@ class SlideshowPictures : public Slideshow { public: SlideshowPictures( QWidget* parent ); - virtual ~SlideshowPictures(); + virtual ~SlideshowPictures() override; QWidget* widget() override; }; -} +} // namespace Calamares #endif From df746047553e635d3cd8dd68b961d9909ee44033 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 13 May 2020 16:35:09 +0200 Subject: [PATCH 05/38] [libcalamaresui] Implement non-QML Slideshow --- src/libcalamaresui/viewpages/Slideshow.cpp | 91 +++++++++++++++++++++- src/libcalamaresui/viewpages/Slideshow.h | 41 +++++++++- 2 files changed, 129 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/viewpages/Slideshow.cpp b/src/libcalamaresui/viewpages/Slideshow.cpp index 5b264a5dd..a6c4c952c 100644 --- a/src/libcalamaresui/viewpages/Slideshow.cpp +++ b/src/libcalamaresui/viewpages/Slideshow.cpp @@ -26,11 +26,15 @@ #include "utils/Qml.h" #include "utils/Retranslator.h" +#include #include #include #include #include #include +#include + +#include namespace Calamares { @@ -61,9 +65,13 @@ SlideshowQML::SlideshowQML( QWidget* parent ) SlideshowQML::~SlideshowQML() { + delete m_qmlObject; + delete m_qmlComponent; + delete m_qmlShow; } -QWidget * SlideshowQML::widget() +QWidget* +SlideshowQML::widget() { return m_qmlShow; } @@ -166,4 +174,83 @@ SlideshowQML::changeSlideShowState( Action state ) m_state = state; } -} // namespace +SlideshowPictures::SlideshowPictures( QWidget* parent ) + : Slideshow( parent ) + , m_label( new QLabel( parent ) ) + , m_timer( new QTimer( this ) ) + , m_imageIndex( 0 ) + , m_images { QStringLiteral( ":/data/images/yes.svgz" ), QStringLiteral( ":/data/images/no.svgz" ) } +{ + m_timer->setInterval( std::chrono::milliseconds( 2000 ) ); + connect( m_timer, &QTimer::timeout, this, &SlideshowPictures::next ); +} + +SlideshowPictures::~SlideshowPictures() +{ + delete m_timer; + delete m_label; +} + +QWidget* +SlideshowPictures::widget() +{ + return m_label; +} + +void +SlideshowPictures::changeSlideShowState( Calamares::Slideshow::Action a ) +{ + QMutexLocker l( &m_mutex ); + m_state = a; + if ( a == Slideshow::Start ) + { + m_imageIndex = -1; + if ( m_images.count() < 1 ) + { + m_label->setPixmap( QPixmap( ":/data/images/squid.svg" ) ); + } + else + { + + m_timer->start(); + QTimer::singleShot( 0, this, &SlideshowPictures::next ); + } + } + else + { + m_timer->stop(); + } +} + +void +SlideshowPictures::next() +{ + QMutexLocker l( &m_mutex ); + + if ( m_imageIndex < 0 ) + { + // Initialization, don't do the advance-by-one + m_imageIndex = 0; + } + else + { + m_imageIndex++; + if ( m_imageIndex >= m_images.count() ) + { + m_imageIndex = 0; + } + } + + if ( m_imageIndex >= m_images.count() ) + { + // Unusual case: timer is running, but we have 0 images to display. + // .. this would have been caught in changeSlideShowState(), which + // .. special-cases 0 images. + return; + } + + m_label->setPixmap( QPixmap( m_images.at( m_imageIndex ) ) ); +} + + +} // namespace Calamares diff --git a/src/libcalamaresui/viewpages/Slideshow.h b/src/libcalamaresui/viewpages/Slideshow.h index 428422db5..2296c6d23 100644 --- a/src/libcalamaresui/viewpages/Slideshow.h +++ b/src/libcalamaresui/viewpages/Slideshow.h @@ -22,8 +22,11 @@ #define LIBCALAMARESUI_SLIDESHOW_H #include +#include #include +class QLabel; +class QTimer; class QQmlComponent; class QQuickItem; class QQuickWidget; @@ -31,6 +34,14 @@ class QQuickWidget; namespace Calamares { +/** @brief API for Slideshow objects + * + * A Slideshow (subclass) object is created by the ExecutionViewStep + * and needs to manage its own configuration (e.g. from Branding). + * The slideshow is started and stopped when it becomes visible + * and when installation is over, by calling changeSlideShowState() + * as appropriate. + */ class Slideshow : public QObject { Q_OBJECT @@ -48,7 +59,7 @@ public: } virtual ~Slideshow(); - ///@brief Is the slideshow being shown **right now**? + /// @brief Is the slideshow being shown **right now**? bool isActive() const { return m_state == Start; } /** @brief The actual widget to show the user. @@ -70,6 +81,15 @@ protected: Action m_state = Stop; }; +/** @brief Slideshow using a QML file + * + * This is the "classic" slideshow in Calamares, which runs some QML + * while the installation is in progress. It is configured through + * Branding settings *slideshow* and *slideshowAPI*, showing the QML + * file from *slideshow*. The API version influences when and how the + * QML is loaded; version 1 does so only when the slideshow is activated, + * while version 2 does so asynchronously. + */ class SlideshowQML : public Slideshow { Q_OBJECT @@ -90,13 +110,32 @@ private: QQuickItem* m_qmlObject; ///< The actual show }; +/** @brief Slideshow using images + * + * This is an "oldschool" slideshow, but new in Calamares, which + * displays static image files one-by-one. It is for systems that + * do not use QML at all. It is configured through the Branding + * setting *slideshow*. When using this widget, the setting must + * be a list of filenames; the API is set to -1. + */ class SlideshowPictures : public Slideshow { + Q_OBJECT public: SlideshowPictures( QWidget* parent ); virtual ~SlideshowPictures() override; QWidget* widget() override; + virtual void changeSlideShowState( Action a ) override; + +public slots: + void next(); + +private: + QLabel* m_label; + QTimer* m_timer; + int m_imageIndex; + QStringList m_images; }; } // namespace Calamares From 5aafa0f4c43b76dc77d561ad7d02352c763aed04 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 13 May 2020 17:19:46 +0200 Subject: [PATCH 06/38] [libcalamaresui] Expose slideshow image names for API -1 - Branding shows the slide pathnames or the slide QML, depending on selected API (which depends on the config-file). - Use one slideshow or the other. --- src/libcalamaresui/Branding.cpp | 18 +++++++++-------- src/libcalamaresui/Branding.h | 10 +++++++++- .../viewpages/ExecutionViewStep.cpp | 20 ++++++++++++++++++- src/libcalamaresui/viewpages/Slideshow.cpp | 2 +- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 87cfda080..0ec691904 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -249,6 +249,7 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) } m_slideshowFilenames = slideShowPictures; + m_slideshowAPI = -1; } else if ( doc[ "slideshow" ].IsScalar() ) { @@ -259,19 +260,20 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) QString( "Slideshow file %1 does not exist or is not a valid QML file." ) .arg( slideshowFi.absoluteFilePath() ) ); m_slideshowPath = slideshowFi.absoluteFilePath(); + + // API choice is relevant for QML slideshow + int api = doc[ "slideshowAPI" ].IsScalar() ? doc[ "slideshowAPI" ].as< int >() : -1; + if ( ( api < 1 ) || ( api > 2 ) ) + { + cWarning() << "Invalid or missing *slideshowAPI* in branding file."; + api = 1; + } + m_slideshowAPI = api; } else { bail( m_descriptorPath, "Syntax error in slideshow sequence." ); } - - int api = doc[ "slideshowAPI" ].IsScalar() ? doc[ "slideshowAPI" ].as< int >() : -1; - if ( ( api < 1 ) || ( api > 2 ) ) - { - cWarning() << "Invalid or missing *slideshowAPI* in branding file."; - api = 1; - } - m_slideshowAPI = api; } catch ( YAML::Exception& e ) { diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 87cb9fffa..1244ede7d 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -165,8 +165,16 @@ public: */ QString translationsDirectory() const { return m_translationsPathPrefix; } - /** @brief Path to the slideshow QML file, if any. */ + /** @brief Path to the slideshow QML file, if any. (API == 1 or 2)*/ QString slideshowPath() const { return m_slideshowPath; } + /// @brief List of pathnames of slideshow images, if any. (API == -1) + QStringList slideshowImages() const { return m_slideshowFilenames; } + /** @brief Which slideshow API to use for the slideshow? + * + * - 2 For QML-based slideshows loaded asynchronously (current) + * - 1 For QML-based slideshows, loaded when shown (legacy) + * - -1 For oldschool image-slideshows. + */ int slideshowAPI() const { return m_slideshowAPI; } QPixmap image( Branding::ImageEntry imageEntry, const QSize& size ) const; diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp index db73d16b1..b4c07bff5 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp @@ -41,6 +41,24 @@ #include #include +static Calamares::Slideshow* +makeSlideshow( QWidget* parent ) +{ + const int api = Calamares::Branding::instance()->slideshowAPI(); + switch ( api ) + { + case -1: + return new Calamares::SlideshowPictures( parent ); + case 1: + FALLTHRU; + case 2: + return new Calamares::SlideshowQML( parent ); + default: + cWarning() << "Unknown Branding slideshow API" << api; + return new Calamares::SlideshowPictures( parent ); + } +} + namespace Calamares { @@ -49,7 +67,7 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) , m_widget( new QWidget ) , m_progressBar( new QProgressBar ) , m_label( new QLabel ) - , m_slideshow( new SlideshowQML( m_widget ) ) + , m_slideshow( makeSlideshow( m_widget ) ) { QVBoxLayout* layout = new QVBoxLayout( m_widget ); QVBoxLayout* innerLayout = new QVBoxLayout; diff --git a/src/libcalamaresui/viewpages/Slideshow.cpp b/src/libcalamaresui/viewpages/Slideshow.cpp index a6c4c952c..497d7dae8 100644 --- a/src/libcalamaresui/viewpages/Slideshow.cpp +++ b/src/libcalamaresui/viewpages/Slideshow.cpp @@ -179,7 +179,7 @@ SlideshowPictures::SlideshowPictures( QWidget* parent ) , m_label( new QLabel( parent ) ) , m_timer( new QTimer( this ) ) , m_imageIndex( 0 ) - , m_images { QStringLiteral( ":/data/images/yes.svgz" ), QStringLiteral( ":/data/images/no.svgz" ) } + , m_images( Branding::instance()->slideshowImages() ) { m_timer->setInterval( std::chrono::milliseconds( 2000 ) ); connect( m_timer, &QTimer::timeout, this, &SlideshowPictures::next ); From 20c1ae246d7bb34d13ebdc7698c26716dbcea1b9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 13 May 2020 17:28:04 +0200 Subject: [PATCH 07/38] [libcalamaresui] Center slideshow pictures --- src/libcalamaresui/viewpages/Slideshow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcalamaresui/viewpages/Slideshow.cpp b/src/libcalamaresui/viewpages/Slideshow.cpp index 497d7dae8..653c9b99d 100644 --- a/src/libcalamaresui/viewpages/Slideshow.cpp +++ b/src/libcalamaresui/viewpages/Slideshow.cpp @@ -181,6 +181,8 @@ SlideshowPictures::SlideshowPictures( QWidget* parent ) , m_imageIndex( 0 ) , m_images( Branding::instance()->slideshowImages() ) { + m_label->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + m_label->setAlignment( Qt::AlignCenter ); m_timer->setInterval( std::chrono::milliseconds( 2000 ) ); connect( m_timer, &QTimer::timeout, this, &SlideshowPictures::next ); } From 6248c6d032d536ab4fafe6a0d09bc0296aa89cbf Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 13 May 2020 17:48:22 +0200 Subject: [PATCH 08/38] [branding] Document slideshow options --- src/branding/default/branding.desc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc index 2e6a02bba..f8cc88295 100644 --- a/src/branding/default/branding.desc +++ b/src/branding/default/branding.desc @@ -141,8 +141,23 @@ images: # The slideshow is displayed during execution steps (e.g. when the # installer is actually writing to disk and doing other slow things). +# +# The slideshow can be a QML file (recommended) which can display +# arbitrary things -- text, images, animations, or even play a game -- +# during the execution step. The QML **is** abruptly stopped when the +# execution step is done, though, so maybe a game isn't a great idea. +# +# The slideshow can also be a sequence of images (not recommended unless +# you don't want QML at all in your Calamares). The images are displayed +# at a rate of 1 every 2 seconds during the execution step. +# +# To configure a QML file, list a single filename: +# slideshow: "show.qml" +# To configure images, like the filenames (here, as an inline list): +# slideshow: [ "/etc/calamares/slideshow/0.png", "/etc/logo.png" ] slideshow: "show.qml" -# There are two available APIs for the slideshow: + +# There are two available APIs for a QML slideshow: # - 1 (the default) loads the entire slideshow when the installation- # slideshow page is shown and starts the QML then. The QML # is never stopped (after installation is done, times etc. @@ -151,6 +166,8 @@ slideshow: "show.qml" # onLeave() in the root object. After the installation is done, # the show is stopped (first by calling onLeave(), then destroying # the QML components). +# +# An image slideshow does not need to have the API defined. slideshowAPI: 2 From c90ebb5d82f1207d2e5abd47f220ae658dccb38c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 01:05:37 +0200 Subject: [PATCH 09/38] [libcalamares] Apply Qt defines consistently - Move some definitions that influence Qt compilation up to the top-level. --- CMakeLists.txt | 6 +++++- src/libcalamares/CMakeLists.txt | 7 +------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ead0b7c4..a2c7dbe6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -496,7 +496,11 @@ if ( CALAMARES_VERSION_RC EQUAL 0 ) endif() # enforce using constBegin, constEnd for const-iterators -add_definitions( "-DQT_STRICT_ITERATORS" ) +add_definitions( + -DQT_STRICT_ITERATORS + -DQT_SHARED + -DQT_SHAREDPOINTER_TRACK_POINTERS +) # set paths set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index dd6f01fb1..6db1cb192 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -1,12 +1,7 @@ # libcalamares is the non-GUI part of Calamares, which includes handling # translations, configurations, logging, utilities, global storage, and (non-GUI) jobs. -add_definitions( - ${QT_DEFINITIONS} - -DQT_SHARED - -DQT_SHAREDPOINTER_TRACK_POINTERS - -DDLLEXPORT_PRO -) +add_definitions( -DDLLEXPORT_PRO ) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CalamaresConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h ) From 13ded5f005568f13612d3da1befea4b8e15a61fb Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 11:53:26 +0200 Subject: [PATCH 10/38] [libcalamares] #include-styling --- src/libcalamares/PythonJobApi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/PythonJobApi.h b/src/libcalamares/PythonJobApi.h index 6fb27cd62..f91572b3d 100644 --- a/src/libcalamares/PythonJobApi.h +++ b/src/libcalamares/PythonJobApi.h @@ -20,10 +20,10 @@ #ifndef PYTHONJOBAPI_H #define PYTHONJOBAPI_H -#include "qglobal.h" // For qreal - #include "utils/BoostPython.h" +#include // For qreal + namespace Calamares { class PythonJob; From 1e09b823b76dcfd0d6c813ea275795d9e3420b6e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 01:12:31 +0200 Subject: [PATCH 11/38] CMake: remove redundant testing configuration - BUILD_TESTING is built-in to CMake, and including CTest turns on all the machinery, so we don't have to do that ourselves. --- CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2c7dbe6d..18b9b116b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,6 @@ set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during develop option( INSTALL_CONFIG "Install configuration files" OFF ) option( INSTALL_POLKIT "Install Polkit configuration" ON ) option( INSTALL_COMPLETION "Install shell completions" OFF ) -option( BUILD_TESTING "Build the testing tree." ON ) option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON ) option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." OFF ) option( WITH_KF5Crash "Enable crash reporting with KCrash." ON ) @@ -159,6 +158,7 @@ if(NOT CMAKE_VERSION VERSION_LESS "3.10.0") ) endif() +include( CTest ) ### C++ SETUP # @@ -312,10 +312,6 @@ if( NOT KF5DBusAddons_FOUND ) set( WITH_KF5DBus OFF ) endif() -if( BUILD_TESTING ) - enable_testing() -endif () - find_package( PythonLibs ${PYTHONLIBS_VERSION} ) set_package_properties( PythonLibs PROPERTIES From cdb99ad887b55fa92b69dfd5aca9916706503090 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 11:15:23 +0200 Subject: [PATCH 12/38] CMake: shuffle WITH_* settings for calamares executable - reminder to make all the ABI-relevant WITH_* settings available as #defines - move the compilation of KDSAG to the calamares executable, not the library - when DBus activation is on, drop all of kdsingleapplicationguard --- CMakeLists.txt | 7 +++++-- src/calamares/CMakeLists.txt | 14 ++++++++++++++ src/libcalamares/CMakeLists.txt | 19 ++----------------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18b9b116b..a9e69a3da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,10 +50,13 @@ set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during develop option( INSTALL_CONFIG "Install configuration files" OFF ) option( INSTALL_POLKIT "Install Polkit configuration" ON ) option( INSTALL_COMPLETION "Install shell completions" OFF ) -option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON ) -option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." OFF ) +# Options for the calamares executable option( WITH_KF5Crash "Enable crash reporting with KCrash." ON ) option( WITH_KF5DBus "Use DBus service for unique-application." OFF ) +# When adding WITH_* that affects the ABI offered by libcalamares, +# also update libcalamares/CalamaresConfig.h.in +option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON ) +option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." OFF ) # Possible debugging flags are: # - DEBUG_TIMEZONES draws latitude and longitude lines on the timezone diff --git a/src/calamares/CMakeLists.txt b/src/calamares/CMakeLists.txt index 5c5a68a97..b632567b8 100644 --- a/src/calamares/CMakeLists.txt +++ b/src/calamares/CMakeLists.txt @@ -10,6 +10,20 @@ set( calamaresSources progresstree/ProgressTreeView.cpp ) +if( NOT WITH_KF5DBus ) + set( kdsagSources "" ) + foreach( _s + kdsingleapplicationguard/kdsingleapplicationguard.cpp + kdsingleapplicationguard/kdsharedmemorylocker.cpp + kdsingleapplicationguard/kdtoolsglobal.cpp + kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp + ) + list( APPEND kdsagSources ${CMAKE_SOURCE_DIR}/3rdparty/${_s} ) + endforeach() + mark_thirdparty_code( ${kdsagSources} ) + list( APPEND calamaresSources ${kdsagSources} ) +endif() + include_directories( ${CMAKE_SOURCE_DIR}/src/libcalamares ${CMAKE_SOURCE_DIR}/src/libcalamaresui diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 6db1cb192..fa4265d6e 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -2,6 +2,7 @@ # translations, configurations, logging, utilities, global storage, and (non-GUI) jobs. add_definitions( -DDLLEXPORT_PRO ) +include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CalamaresConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h ) @@ -60,22 +61,6 @@ set( libSources utils/Variant.cpp utils/Yaml.cpp ) -set( _kdsagSources - kdsingleapplicationguard/kdsingleapplicationguard.cpp - kdsingleapplicationguard/kdsharedmemorylocker.cpp - kdsingleapplicationguard/kdtoolsglobal.cpp - kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp -) -set( kdsagSources "" ) -foreach( _s ${_kdsagSources} ) - list( APPEND kdsagSources ${CMAKE_SOURCE_DIR}/3rdparty/${_s} ) -endforeach() -mark_thirdparty_code( ${kdsagSources} ) - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} -) ### OPTIONAL Python support # @@ -151,7 +136,7 @@ endif() ### LIBRARY # # -add_library( calamares SHARED ${libSources} ${kdsagSources} ) +add_library( calamares SHARED ${libSources} ) set_target_properties( calamares PROPERTIES VERSION ${CALAMARES_VERSION_SHORT} From 2b0b873159dcec8f62b1bbbd0bcd95234c6845f9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 15:23:45 +0200 Subject: [PATCH 13/38] [welcome] Remove spurious logging --- src/modules/welcome/checker/GeneralRequirements.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/welcome/checker/GeneralRequirements.cpp b/src/modules/welcome/checker/GeneralRequirements.cpp index f30950da2..ba6ebe89f 100644 --- a/src/modules/welcome/checker/GeneralRequirements.cpp +++ b/src/modules/welcome/checker/GeneralRequirements.cpp @@ -80,7 +80,6 @@ struct MaybeChecked MaybeChecked& operator=( bool b ) { - cDebug() << "Assigning" << b; hasBeenChecked = true; value = b; return *this; From 0235245631363016ef34977b94a9a8a2eb155749 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 15:55:41 +0200 Subject: [PATCH 14/38] [libcalamares] #include-styling --- src/libcalamares/DllMacro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamares/DllMacro.h b/src/libcalamares/DllMacro.h index 712bf5732..528a70c2d 100644 --- a/src/libcalamares/DllMacro.h +++ b/src/libcalamares/DllMacro.h @@ -20,7 +20,7 @@ #ifndef DLLMACRO_H #define DLLMACRO_H -#include +#include /* * Mark symbols exported from Calamares non-GUI library with DLLEXPORT. From 47979555fec0aa19f33a3dc37ec4a66c9e9c118e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 15:54:19 +0200 Subject: [PATCH 15/38] CMake: optionally disable QML This makes it possible to remove QML from Calamares, possibly yielding a smaller, lighter installer; it takes with it the nice slideshow, modern configurable navigation and the QML UIs built for various modules. By default, WITH_QML is on and the "normal" feature set is retained. - look for Qml modules only when WITH_QML is on (the default) - look for Network, since that's pulled in only implicitly - disable the QML Calamares models (modules/*q) if no QML is enabled; longer-term plan is to merge the **pages** back to the "upstream" modules, and have things be run-time switchable, but that's not here yet. Also disable the notesqml module when QML is off. --- CMakeLists.txt | 8 ++++++-- src/libcalamares/CalamaresConfig.h.in | 1 + src/modules/keyboardq/CMakeLists.txt | 5 +++++ src/modules/localeq/CMakeLists.txt | 5 +++++ src/modules/notesqml/CMakeLists.txt | 5 +++++ src/modules/welcomeq/CMakeLists.txt | 5 +++++ 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a9e69a3da..519ee1abc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,8 @@ option( WITH_KF5DBus "Use DBus service for unique-application." OFF ) # When adding WITH_* that affects the ABI offered by libcalamares, # also update libcalamares/CalamaresConfig.h.in option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON ) -option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." OFF ) +option( WITH_PYTHONQT "Enable Python view modules API (deprecated, requires PythonQt)." OFF ) +option( WITH_QML "Enable QML UI options." ON ) # Possible debugging flags are: # - DEBUG_TIMEZONES draws latitude and longitude lines on the timezone @@ -253,7 +254,10 @@ include( CMakeColors ) ### DEPENDENCIES # -find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui Widgets LinguistTools Svg Quick QuickWidgets ) +find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui LinguistTools Network Svg Widgets ) +if( WITH_QML ) + find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Quick QuickWidgets ) +endif() if( Qt5_VERSION VERSION_GREATER 5.12.1 ) # At least Qt 5.12.2 seems to support Esperanto in QLocale if( "eo" IN_LIST _tx_incomplete ) diff --git a/src/libcalamares/CalamaresConfig.h.in b/src/libcalamares/CalamaresConfig.h.in index 55468cf15..b31de95b5 100644 --- a/src/libcalamares/CalamaresConfig.h.in +++ b/src/libcalamares/CalamaresConfig.h.in @@ -11,5 +11,6 @@ //cmakedefines for CMake variables (e.g. for optdepends) go here #cmakedefine WITH_PYTHON #cmakedefine WITH_PYTHONQT +#cmakedefine WITH_QML #endif // CALAMARESCONFIG_H diff --git a/src/modules/keyboardq/CMakeLists.txt b/src/modules/keyboardq/CMakeLists.txt index f5fd2b64b..729748a7f 100644 --- a/src/modules/keyboardq/CMakeLists.txt +++ b/src/modules/keyboardq/CMakeLists.txt @@ -1,3 +1,8 @@ +if( NOT WITH_QML ) + calamares_skip_module( "keyboardq (QML is not supported in this build)" ) + return() +endif() + set( _keyboard ${CMAKE_CURRENT_SOURCE_DIR}/../keyboard ) include_directories( ${_keyboard} ) diff --git a/src/modules/localeq/CMakeLists.txt b/src/modules/localeq/CMakeLists.txt index 280c95c62..c9ed1cd55 100644 --- a/src/modules/localeq/CMakeLists.txt +++ b/src/modules/localeq/CMakeLists.txt @@ -1,3 +1,8 @@ +if( NOT WITH_QML ) + calamares_skip_module( "localeq (QML is not supported in this build)" ) + return() +endif() + # When debugging the timezone widget, add this debugging definition # to have a debugging-friendly timezone widget, debug logging, # and no intrusive timezone-setting while clicking around. diff --git a/src/modules/notesqml/CMakeLists.txt b/src/modules/notesqml/CMakeLists.txt index 6aedab5aa..7ac808fa7 100644 --- a/src/modules/notesqml/CMakeLists.txt +++ b/src/modules/notesqml/CMakeLists.txt @@ -1,3 +1,8 @@ +if( NOT WITH_QML ) + calamares_skip_module( "notesqml (QML is not supported in this build)" ) + return() +endif() + calamares_add_plugin( notesqml TYPE viewmodule EXPORT_MACRO PLUGINDLLEXPORT_PRO diff --git a/src/modules/welcomeq/CMakeLists.txt b/src/modules/welcomeq/CMakeLists.txt index 9cb89c3d9..4a040344e 100644 --- a/src/modules/welcomeq/CMakeLists.txt +++ b/src/modules/welcomeq/CMakeLists.txt @@ -1,6 +1,11 @@ # This is a re-write of the welcome module using QML view steps # instead of widgets. +if( NOT WITH_QML ) + calamares_skip_module( "welcomeq (QML is not supported in this build)" ) + return() +endif() + set( _welcome ${CMAKE_CURRENT_SOURCE_DIR}/../welcome ) include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ${CMAKE_CURRENT_SOURCE_DIR}/../../libcalamares ${_welcome} ) From 736f99768a7ab79a6585a5bba8ad75eef5b24b8c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 16:18:52 +0200 Subject: [PATCH 16/38] [libcalamaresui] Don't build QML bits if they're not wanted When WITH_QML is off (by explicit choice) - don't build the QmlViewStep - don't build the QML slideshow --- src/libcalamaresui/CMakeLists.txt | 28 ++++++++++--------- .../viewpages/ExecutionViewStep.cpp | 4 ++- src/libcalamaresui/viewpages/Slideshow.cpp | 4 +++ src/libcalamaresui/viewpages/Slideshow.h | 6 ++++ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index ee7992710..c5c7e9d4b 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -14,11 +14,9 @@ set( calamaresui_SOURCES utils/CalamaresUtilsGui.cpp utils/ImageRegistry.cpp utils/Paste.cpp - utils/Qml.cpp viewpages/BlankViewStep.cpp viewpages/ExecutionViewStep.cpp - viewpages/QmlViewStep.cpp viewpages/Slideshow.cpp viewpages/ViewStep.cpp @@ -45,10 +43,6 @@ if( WITH_PYTHON ) endif() if( WITH_PYTHONQT ) - include_directories(${PYTHON_INCLUDE_DIRS}) - # *_DIRS because we also use extensions - include_directories(${PYTHONQT_INCLUDE_DIRS}) - list( APPEND calamaresui_SOURCES modulesystem/PythonQtViewModule.cpp utils/PythonQtUtils.cpp @@ -57,25 +51,33 @@ if( WITH_PYTHONQT ) viewpages/PythonQtGlobalStorageWrapper.cpp viewpages/PythonQtUtilsWrapper.cpp ) - set( OPTIONAL_PYTHON_LIBRARIES - ${PYTHON_LIBRARIES} - ${PYTHONQT_LIBRARIES} +endif() + +if( WITH_QML ) + list( APPEND calamaresui_SOURCES + utils/Qml.cpp + viewpages/QmlViewStep.cpp ) endif() calamares_add_library( calamaresui SOURCES ${calamaresui_SOURCES} EXPORT_MACRO UIDLLEXPORT_PRO - LINK_PRIVATE_LIBRARIES - ${OPTIONAL_PYTHON_LIBRARIES} LINK_LIBRARIES Qt5::Svg - Qt5::QuickWidgets RESOURCES libcalamaresui.qrc EXPORT CalamaresLibraryDepends VERSION ${CALAMARES_VERSION_SHORT} ) -if ( KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58 ) +if( KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58 ) target_compile_definitions( calamaresui PRIVATE WITH_KOSRelease ) endif() +if( WITH_PYTHONQT ) + # *_DIRS because we also use extensions + target_include_directories( calamaresui PRIVATE ${PYTHON_INCLUDE_DIRS} ${PYTHONQT_INCLUDE_DIRS} ) + target_link_libraries( calamaresui PRIVATE ${PYTHON_LIBRARIES} ${PYTHONQT_LIBRARIES} ) +endif() +if( WITH_QML ) + target_link_libraries( calamaresui PUBLIC Qt5::QuickWidgets ) +endif() diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp index b4c07bff5..2dd4b79df 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp @@ -23,11 +23,11 @@ #include "Slideshow.h" #include "Branding.h" +#include "CalamaresConfig.h" #include "Job.h" #include "JobQueue.h" #include "Settings.h" #include "ViewManager.h" - #include "modulesystem/Module.h" #include "modulesystem/ModuleManager.h" #include "utils/CalamaresUtilsGui.h" @@ -49,10 +49,12 @@ makeSlideshow( QWidget* parent ) { case -1: return new Calamares::SlideshowPictures( parent ); +#ifdef WITH_QML case 1: FALLTHRU; case 2: return new Calamares::SlideshowQML( parent ); +#endif default: cWarning() << "Unknown Branding slideshow API" << api; return new Calamares::SlideshowPictures( parent ); diff --git a/src/libcalamaresui/viewpages/Slideshow.cpp b/src/libcalamaresui/viewpages/Slideshow.cpp index 653c9b99d..85551f797 100644 --- a/src/libcalamaresui/viewpages/Slideshow.cpp +++ b/src/libcalamaresui/viewpages/Slideshow.cpp @@ -28,10 +28,12 @@ #include #include +#ifdef WITH_QML #include #include #include #include +#endif #include #include @@ -41,6 +43,7 @@ namespace Calamares Slideshow::~Slideshow() {} +#ifdef WITH_QML SlideshowQML::SlideshowQML( QWidget* parent ) : Slideshow( parent ) , m_qmlShow( new QQuickWidget ) @@ -173,6 +176,7 @@ SlideshowQML::changeSlideShowState( Action state ) m_state = state; } +#endif SlideshowPictures::SlideshowPictures( QWidget* parent ) : Slideshow( parent ) diff --git a/src/libcalamaresui/viewpages/Slideshow.h b/src/libcalamaresui/viewpages/Slideshow.h index 2296c6d23..f338d44e2 100644 --- a/src/libcalamaresui/viewpages/Slideshow.h +++ b/src/libcalamaresui/viewpages/Slideshow.h @@ -21,15 +21,19 @@ #ifndef LIBCALAMARESUI_SLIDESHOW_H #define LIBCALAMARESUI_SLIDESHOW_H +#include "CalamaresConfig.h" + #include #include #include class QLabel; class QTimer; +#ifdef WITH_QML class QQmlComponent; class QQuickItem; class QQuickWidget; +#endif namespace Calamares { @@ -81,6 +85,7 @@ protected: Action m_state = Stop; }; +#ifdef WITH_QML /** @brief Slideshow using a QML file * * This is the "classic" slideshow in Calamares, which runs some QML @@ -109,6 +114,7 @@ private: QQmlComponent* m_qmlComponent; QQuickItem* m_qmlObject; ///< The actual show }; +#endif /** @brief Slideshow using images * From c83e5c57a455e2c91c60fbadc5b6f006c8ef4ecf Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 16:56:50 +0200 Subject: [PATCH 17/38] [libcalamaresui] When QML is off, there is no Qml panel flavor --- src/calamares/CalamaresWindow.cpp | 48 ++++++++++++++++++++++--------- src/libcalamaresui/Branding.cpp | 5 +++- src/libcalamaresui/Branding.h | 7 +++-- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp index 06a31a0e9..2ab7cd5fa 100644 --- a/src/calamares/CalamaresWindow.cpp +++ b/src/calamares/CalamaresWindow.cpp @@ -22,6 +22,7 @@ #include "CalamaresWindow.h" #include "Branding.h" +#include "CalamaresConfig.h" #include "DebugWindow.h" #include "Settings.h" #include "ViewManager.h" @@ -38,8 +39,10 @@ #include #include #include +#ifdef WITH_QML #include #include +#endif #include static inline int @@ -132,18 +135,6 @@ CalamaresWindow::getWidgetSidebar( QWidget* parent, int desiredWidth ) return sideBox; } -QWidget* -CalamaresWindow::getQmlSidebar( QWidget* parent, int ) -{ - CalamaresUtils::registerCalamaresModels(); - QQuickWidget* w = new QQuickWidget( parent ); - w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); - w->setResizeMode( QQuickWidget::SizeRootObjectToView ); - w->setSource( QUrl( - CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-sidebar" ) ) ) ); - return w; -} - /** @brief Get a button-sized icon. */ static inline QPixmap getButtonIcon( const QString& name ) @@ -213,6 +204,19 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent ) return navigation; } +#ifdef WITH_QML +QWidget* +CalamaresWindow::getQmlSidebar( QWidget* parent, int ) +{ + CalamaresUtils::registerCalamaresModels(); + QQuickWidget* w = new QQuickWidget( parent ); + w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + w->setResizeMode( QQuickWidget::SizeRootObjectToView ); + w->setSource( QUrl( + CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-sidebar" ) ) ) ); + return w; +} + QWidget* CalamaresWindow::getQmlNavigation( QWidget* parent ) { @@ -231,6 +235,19 @@ CalamaresWindow::getQmlNavigation( QWidget* parent ) return w; } +#else +// Bogus to keep the linker happy +QWidget * CalamaresWindow::getQmlSidebar(QWidget* , int ) +{ + return nullptr; +} +QWidget * CalamaresWindow::getQmlNavigation(QWidget* ) +{ + return nullptr; +} + + +#endif /**@brief Picks one of two methods to call * @@ -243,16 +260,21 @@ flavoredWidget( Calamares::Branding::PanelFlavor flavor, CalamaresWindow* w, QWidget* parent, widgetMaker widget, - widgetMaker qml, + widgetMaker qml, // Only if WITH_QML is on args... a ) { +#ifndef WITH_QML + Q_UNUSED( qml ) +#endif // Member-function calling syntax is (object.*member)(args) switch ( flavor ) { case Calamares::Branding::PanelFlavor::Widget: return ( w->*widget )( parent, a... ); +#ifdef WITH_QML case Calamares::Branding::PanelFlavor::Qml: return ( w->*qml )( parent, a... ); +#endif case Calamares::Branding::PanelFlavor::None: return nullptr; } diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 0ec691904..2eb64e875 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -436,8 +436,11 @@ flavorAndSide( const YAML::Node& doc, const char* key, Branding::PanelFlavor& fl static const NamedEnumTable< PanelFlavor > sidebarFlavorNames { { QStringLiteral( "widget" ), PanelFlavor::Widget }, { QStringLiteral( "none" ), PanelFlavor::None }, - { QStringLiteral( "hidden" ), PanelFlavor::None }, + { QStringLiteral( "hidden" ), PanelFlavor::None } +#ifdef WITH_QML + , { QStringLiteral( "qml" ), PanelFlavor::Qml } +#endif }; static const NamedEnumTable< PanelSide > panelSideNames { { QStringLiteral( "left" ), PanelSide::Left }, diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 1244ede7d..0723d9287 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -22,8 +22,8 @@ #ifndef BRANDING_H #define BRANDING_H +#include "CalamaresConfig.h" #include "DllMacro.h" - #include "utils/NamedSuffix.h" #include @@ -131,8 +131,11 @@ public: enum class PanelFlavor { None, - Widget, + Widget +#ifdef WITH_QML + , Qml +#endif }; Q_ENUM( PanelFlavor ) ///@brief Where to place a panel (sidebar, navigation) From 022045ae0580296890481678f452f56fababe3c6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 14 May 2020 17:04:35 +0200 Subject: [PATCH 18/38] [libcalamaresui] Refactor loading slideshow - split into a separate method - when QML is disabled, warn about QML settings --- src/libcalamaresui/Branding.cpp | 109 ++++++++++++++++++-------------- src/libcalamaresui/Branding.h | 2 + 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 2eb64e875..a5909fd61 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -180,6 +180,7 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) "component directory." ); initSimpleSettings( doc ); + initSlideshowSettings( doc ); #ifdef WITH_KOSRelease // Copy the os-release information into a QHash for use by KMacroExpander. @@ -202,17 +203,15 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) { QStringLiteral( "VARIANT" ), relInfo.variant() }, { QStringLiteral( "VARIANT_ID" ), relInfo.variantId() }, { QStringLiteral( "LOGO" ), relInfo.logo() } } }; - auto expand = [ & ]( const QString& s ) -> QString { + auto expand = [&]( const QString& s ) -> QString { return KMacroExpander::expandMacros( s, relMap, QLatin1Char( '@' ) ); }; #else auto expand = []( const QString& s ) -> QString { return s; }; #endif - - // Massage the strings, images and style sections. loadStrings( m_strings, doc, "strings", expand ); - loadStrings( m_images, doc, "images", [ & ]( const QString& s ) -> QString { + loadStrings( m_images, doc, "images", [&]( const QString& s ) -> QString { // See also image() const QString imageName( expand( s ) ); QFileInfo imageFi( componentDir.absoluteFilePath( imageName ) ); @@ -230,50 +229,6 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent ) return imageFi.absoluteFilePath(); } ); loadStrings( m_style, doc, "style", []( const QString& s ) -> QString { return s; } ); - - if ( doc[ "slideshow" ].IsSequence() ) - { - QStringList slideShowPictures; - doc[ "slideshow" ] >> slideShowPictures; - for ( int i = 0; i < slideShowPictures.count(); ++i ) - { - QString pathString = slideShowPictures[ i ]; - QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) ); - if ( !imageFi.exists() ) - { - bail( m_descriptorPath, - QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) ); - } - - slideShowPictures[ i ] = imageFi.absoluteFilePath(); - } - - m_slideshowFilenames = slideShowPictures; - m_slideshowAPI = -1; - } - else if ( doc[ "slideshow" ].IsScalar() ) - { - QString slideshowPath = QString::fromStdString( doc[ "slideshow" ].as< std::string >() ); - QFileInfo slideshowFi( componentDir.absoluteFilePath( slideshowPath ) ); - if ( !slideshowFi.exists() || !slideshowFi.fileName().toLower().endsWith( ".qml" ) ) - bail( m_descriptorPath, - QString( "Slideshow file %1 does not exist or is not a valid QML file." ) - .arg( slideshowFi.absoluteFilePath() ) ); - m_slideshowPath = slideshowFi.absoluteFilePath(); - - // API choice is relevant for QML slideshow - int api = doc[ "slideshowAPI" ].IsScalar() ? doc[ "slideshowAPI" ].as< int >() : -1; - if ( ( api < 1 ) || ( api > 2 ) ) - { - cWarning() << "Invalid or missing *slideshowAPI* in branding file."; - api = 1; - } - m_slideshowAPI = api; - } - else - { - bail( m_descriptorPath, "Syntax error in slideshow sequence." ); - } } catch ( YAML::Exception& e ) { @@ -556,4 +511,62 @@ Branding::initSimpleSettings( const YAML::Node& doc ) } } +void +Branding::initSlideshowSettings( const YAML::Node& doc ) +{ + QDir componentDir( componentDirectory() ); + + if ( doc[ "slideshow" ].IsSequence() ) + { + QStringList slideShowPictures; + doc[ "slideshow" ] >> slideShowPictures; + for ( int i = 0; i < slideShowPictures.count(); ++i ) + { + QString pathString = slideShowPictures[ i ]; + QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) ); + if ( !imageFi.exists() ) + { + bail( m_descriptorPath, + QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) ); + } + + slideShowPictures[ i ] = imageFi.absoluteFilePath(); + } + + m_slideshowFilenames = slideShowPictures; + m_slideshowAPI = -1; + } +#ifdef WITH_QML + else if ( doc[ "slideshow" ].IsScalar() ) + { + QString slideshowPath = QString::fromStdString( doc[ "slideshow" ].as< std::string >() ); + QFileInfo slideshowFi( componentDir.absoluteFilePath( slideshowPath ) ); + if ( !slideshowFi.exists() || !slideshowFi.fileName().toLower().endsWith( ".qml" ) ) + bail( m_descriptorPath, + QString( "Slideshow file %1 does not exist or is not a valid QML file." ) + .arg( slideshowFi.absoluteFilePath() ) ); + m_slideshowPath = slideshowFi.absoluteFilePath(); + + // API choice is relevant for QML slideshow + int api = doc[ "slideshowAPI" ].IsScalar() ? doc[ "slideshowAPI" ].as< int >() : -1; + if ( ( api < 1 ) || ( api > 2 ) ) + { + cWarning() << "Invalid or missing *slideshowAPI* in branding file."; + api = 1; + } + m_slideshowAPI = api; + } +#else + else if ( doc[ "slideshow" ].IsScalar() ) + { + cWarning() << "Invalid *slideshow* setting, must be list of images."; + } +#endif + else + { + bail( m_descriptorPath, "Syntax error in slideshow sequence." ); + } +} + + } // namespace Calamares diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 0723d9287..e84e23680 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -262,6 +262,8 @@ private: /** @brief Initialize the simple settings below */ void initSimpleSettings( const YAML::Node& doc ); + ///@brief Initialize the slideshow settings, above + void initSlideshowSettings( const YAML::Node& doc ); bool m_welcomeStyleCalamares; bool m_welcomeExpandingLogo; From fed89badd4da3e9ac56e4f0f083e17fe8d37d3af Mon Sep 17 00:00:00 2001 From: demmm Date: Thu, 14 May 2020 19:00:02 +0200 Subject: [PATCH 19/38] [welcomeq] connected to RequirementsModel clean up obsolete lines in welcomeq.qml add requirement section from welcome.conf to welcomeq.conf data shows correctly in Recommended.qml, fails to show any in Requirements.qml if run without admin rights --- src/modules/welcomeq/Recommended.qml | 69 ++++++++++++++++++-------- src/modules/welcomeq/Requirements.qml | 70 +++++++++++++++++++-------- src/modules/welcomeq/welcomeq.conf | 37 ++++++++++++++ src/modules/welcomeq/welcomeq.qml | 6 --- 4 files changed, 138 insertions(+), 44 deletions(-) diff --git a/src/modules/welcomeq/Recommended.qml b/src/modules/welcomeq/Recommended.qml index 373509104..9bc0ef619 100644 --- a/src/modules/welcomeq/Recommended.qml +++ b/src/modules/welcomeq/Recommended.qml @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2020, Anke Boersma + * Copyright 2020, Adriaan de Groot * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +17,7 @@ * along with Calamares. If not, see . */ +import io.calamares.core 1.0 import io.calamares.ui 1.0 import QtQuick 2.7 @@ -33,35 +35,64 @@ Rectangle { id: recommended anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - anchors.topMargin: 20 + anchors.topMargin: 10 + horizontalAlignment: TextEdit.AlignHCenter width: 640 - font.pointSize: 12 + font.pointSize: 11 textFormat: Text.RichText antialiasing: true activeFocusOnPress: false wrapMode: Text.WordWrap - text: qsTr("

This computer does not satisfy some of the recommended requirements for setting up %1.

-

Setup can continue, but some features might be disabled.

").arg(Branding.string(Branding.VersionedName)) + text: qsTr("

This computer does not satisfy some of the recommended requirements for setting up %1.
+ Setup can continue, but some features might be disabled.

").arg(Branding.string(Branding.VersionedName)) } - TextArea { + Rectangle { + width: 640 + height: 400 anchors.horizontalCenter: parent.horizontalCenter anchors.top: recommended.bottom - anchors.topMargin: 20 - width: 640 - background: Rectangle { - implicitWidth: 640 - implicitHeight: 50 - border.color: "#ff0000" - color: "#b0e0e6" - } - font.pointSize: 12 - textFormat: Text.RichText - antialiasing: true - activeFocusOnPress: false - wrapMode: Text.WordWrap + anchors.topMargin: 5 - text: qsTr("

The system is not connected to the internet.

")//.arg(requirementsModel) + Component { + id: requirementsDelegate + + Item { + width: 640 + height: 40 + + Column { + anchors.centerIn: parent + + Rectangle { + implicitWidth: 640 + implicitHeight: 40 + border.color: satisfied ? "#228b22" : "#ffa411" + color: satisfied ? "#f0fff0" : "#ffefd5" + + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.margins: 20 + source: satisfied ? "qrc:/data/images/yes.svgz" : "qrc:/data/images/information.svgz" + } + + Text { + text: ( satisfied ? 'Met: ' : 'Missing: ' ) + name + " " + details + anchors.centerIn: parent + font.pointSize: 12 + } + } + } + } + } + + ListView { + anchors.fill: parent + spacing: 5 + model: config.requirementsModel + delegate: requirementsDelegate + } } } diff --git a/src/modules/welcomeq/Requirements.qml b/src/modules/welcomeq/Requirements.qml index 4f5520270..b12caf6f6 100644 --- a/src/modules/welcomeq/Requirements.qml +++ b/src/modules/welcomeq/Requirements.qml @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2020, Anke Boersma + * Copyright 2020, Adriaan de Groot * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +17,7 @@ * along with Calamares. If not, see . */ +import io.calamares.core 1.0 import io.calamares.ui 1.0 import QtQuick 2.7 @@ -33,35 +35,65 @@ Rectangle { id: required anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - anchors.topMargin: 20 + anchors.topMargin: 10 + horizontalAlignment: TextEdit.AlignHCenter width: 640 - font.pointSize: 12 + font.pointSize: 11 textFormat: Text.RichText antialiasing: true activeFocusOnPress: false wrapMode: Text.WordWrap - text: qsTr("

This computer does not satisfy the minimum requirements for setting up %1.

-

Setup cannot continue.

").arg(Branding.string(Branding.VersionedName)) + text: qsTr("

This computer does not satisfy the minimum requirements for installing %1.
+ Installation cannot continue.

").arg(Branding.string(Branding.VersionedName)) } - TextArea { + Rectangle { + width: 640 + height: 400 anchors.horizontalCenter: parent.horizontalCenter anchors.top: required.bottom - anchors.topMargin: 20 - width: 640 - background: Rectangle { - implicitWidth: 640 - implicitHeight: 50 - border.color: "#ff0000" - color: "#ffc0cb" - } - font.pointSize: 12 - textFormat: Text.RichText - antialiasing: true - activeFocusOnPress: false - wrapMode: Text.WordWrap + anchors.topMargin: 5 - text: qsTr("

The installer is not running with administrator rights.

")//.arg(requirementsModel) + Component { + id: requirementsDelegate + + Item { + width: 640 + height: 40 + + Column { + anchors.centerIn: parent + + Rectangle { + implicitWidth: 640 + implicitHeight: 40 + border.color: mandatory ? "#ff0000" : "#228b22" + color: mandatory ? "#ffc0cb" : "#f0fff0" + + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.margins: 20 + source: mandatory ? "qrc:/data/images/yes.svgz" : "qrc:/data/images/no.svgz" + } + + Text { + text: ( mandatory ? 'Met: ' : 'Failed: ' ) + name + " " + details + anchors.centerIn: parent + font.pointSize: 12 + } + } + } + } + } + + ListView { + anchors.fill: parent + spacing: 5 + model: config.requirementsModel + delegate: requirementsDelegate + } } } + diff --git a/src/modules/welcomeq/welcomeq.conf b/src/modules/welcomeq/welcomeq.conf index a5ab97f50..2553e157a 100644 --- a/src/modules/welcomeq/welcomeq.conf +++ b/src/modules/welcomeq/welcomeq.conf @@ -25,3 +25,40 @@ showReleaseNotesUrl: true # branding.desc string) # # showDonateUrl: https://kde.org/community/donations/ + +# Requirements checking. These are general, generic, things +# that are checked. They may not match with the actual requirements +# imposed by other modules in the system. +requirements: + # Amount of available disk, in GiB. Floating-point is allowed here. + # Note that this does not account for *usable* disk, so it is possible + # to pass this requirement, yet have no space to install to. + requiredStorage: 5.5 + + # Amount of available RAM, in GiB. Floating-point is allowed here. + requiredRam: 1.0 + + # To check for internet connectivity, Calamares does a HTTP GET + # on this URL; on success (e.g. HTTP code 200) internet is OK. + internetCheckUrl: http://google.com + + # List conditions to check. Each listed condition will be + # probed in some way, and yields true or false according to + # the host system satisfying the condition. + # + # This sample file lists all the conditions that are known. + check: + - storage + - ram + - power + - internet + - root + - screen + # List conditions that **must** be satisfied (from the list + # of conditions, above) for installation to proceed. + # If any of these conditions are not met, the user cannot + # continue past the welcome page. + required: + # - storage + - ram + # - root diff --git a/src/modules/welcomeq/welcomeq.qml b/src/modules/welcomeq/welcomeq.qml index 2a29c5d9a..b92ff9628 100644 --- a/src/modules/welcomeq/welcomeq.qml +++ b/src/modules/welcomeq/welcomeq.qml @@ -57,16 +57,10 @@ Page } Recommended { - property var required: "yes" //requirementsModel - property var satisfied: "yes" //satisfiedRequirements - property var requiredMet: (required != satisfied) ? true : false visible: !config.requirementsModel.satisfiedRequirements } Requirements { - property var required: "yes" //requirementsModel - property var mandatory: "yes" //satisfiedMandatory - property var mandatoryMet: (required != mandatory) ? true : false visible: !config.requirementsModel.satisfiedMandatory } From a85ff30ad44dbbdc75f04758545a9677a1fdc4bc Mon Sep 17 00:00:00 2001 From: demmm Date: Thu, 14 May 2020 20:01:50 +0200 Subject: [PATCH 20/38] [welcomeq] smaller font size correct color order Requirements.qml --- src/modules/welcomeq/Recommended.qml | 2 +- src/modules/welcomeq/Requirements.qml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/welcomeq/Recommended.qml b/src/modules/welcomeq/Recommended.qml index 9bc0ef619..3fedb3282 100644 --- a/src/modules/welcomeq/Recommended.qml +++ b/src/modules/welcomeq/Recommended.qml @@ -81,7 +81,7 @@ Rectangle { Text { text: ( satisfied ? 'Met: ' : 'Missing: ' ) + name + " " + details anchors.centerIn: parent - font.pointSize: 12 + font.pointSize: 11 } } } diff --git a/src/modules/welcomeq/Requirements.qml b/src/modules/welcomeq/Requirements.qml index b12caf6f6..a1f318532 100644 --- a/src/modules/welcomeq/Requirements.qml +++ b/src/modules/welcomeq/Requirements.qml @@ -68,8 +68,8 @@ Rectangle { Rectangle { implicitWidth: 640 implicitHeight: 40 - border.color: mandatory ? "#ff0000" : "#228b22" - color: mandatory ? "#ffc0cb" : "#f0fff0" + border.color: mandatory ? "#228b22" : "#ff0000" + color: mandatory ? "#f0fff0" : "#ffc0cb" Image { anchors.verticalCenter: parent.verticalCenter @@ -81,7 +81,7 @@ Rectangle { Text { text: ( mandatory ? 'Met: ' : 'Failed: ' ) + name + " " + details anchors.centerIn: parent - font.pointSize: 12 + font.pointSize: 11 } } } From 153d605bb668a8d1a8b72cc37b53fff6564f7090 Mon Sep 17 00:00:00 2001 From: demmm Date: Thu, 14 May 2020 23:11:05 +0200 Subject: [PATCH 21/38] [welcomeq] use negatedText for better text on missing --- src/modules/welcomeq/Recommended.qml | 2 +- src/modules/welcomeq/Requirements.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/welcomeq/Recommended.qml b/src/modules/welcomeq/Recommended.qml index 3fedb3282..7144cbd9a 100644 --- a/src/modules/welcomeq/Recommended.qml +++ b/src/modules/welcomeq/Recommended.qml @@ -79,7 +79,7 @@ Rectangle { } Text { - text: ( satisfied ? 'Met: ' : 'Missing: ' ) + name + " " + details + text: satisfied ? details : negatedText anchors.centerIn: parent font.pointSize: 11 } diff --git a/src/modules/welcomeq/Requirements.qml b/src/modules/welcomeq/Requirements.qml index a1f318532..00a045041 100644 --- a/src/modules/welcomeq/Requirements.qml +++ b/src/modules/welcomeq/Requirements.qml @@ -79,7 +79,7 @@ Rectangle { } Text { - text: ( mandatory ? 'Met: ' : 'Failed: ' ) + name + " " + details + text: mandatory ? details : negatedText anchors.centerIn: parent font.pointSize: 11 } From e524ac952d6fad6d277ca51b85fc1a9e2c3c335f Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Thu, 14 May 2020 23:52:59 +0200 Subject: [PATCH 22/38] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_fa.ts | 295 ++++++++++++++++++++-------------------- lang/calamares_zh_CN.ts | 30 +++- 2 files changed, 175 insertions(+), 150 deletions(-) diff --git a/lang/calamares_fa.ts b/lang/calamares_fa.ts index 0375254d3..a4de510ad 100644 --- a/lang/calamares_fa.ts +++ b/lang/calamares_fa.ts @@ -6,17 +6,17 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - + <strong>محیط بوت</strong> این سیستم. <br><br>سیستم‌های قدیمی x86 فقط از <strong>بایوس</strong> پشتیبانی می‌کنند. <br>سیستم‌های مدرن معمولا از <strong>ای.اف.آی</strong> استفاده می‌کنند، اما ممکن است در صورتی که در حالت سازگاری اجرا شوند همچنان به صورت بایوس نشان داده شوند This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. - + سیستم با محیط بوت <strong>ای.اف.آی</strong> آغاز شد. <br><br>به منظور پیکربندی راه‌اندازی از یک محیط ای.اف.آی، این نصاب باید حتما‌ یک برنامه بالاآورنده بوت، مانند <strong>گراب</strong> یا <strong>سیستم‌بوت</strong> را روی یک پارتیشن سیستم ای.اف.آی مستقر نماید. این به صورت خودکار است مگر اینکه شما پارتیشن‌بندی دستی را انتخاب کنید که در این صورت باید خودتان انتخاب کنید یا به صورت دستی ایجاد کنید. This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. - + سیستم با محیط بوت <strong>بایوس</strong> آغاز شد. <br><br>به منظور پیکربندی راه‌انداری از یک محیط بایوس، این نصاب باید حتما‌ یک برنامه بالاآورنده بوت، مانند <strong>گراب</strong> را یا در شروع یک پارتیشن و یا روی <strong>رکورد راه‌انداز اصلی</strong> نزدیک شروع جدول پارتیشن (ترجیحا) نصب کند. این به صورت خودکار است مگر اینکه شما پارتیشن‌بندی دستی را انتخاب کنید که در این صورت باید خودتان به صورت دستی آن را راه‌اندازی کنید. @@ -24,27 +24,27 @@ Master Boot Record of %1 - + رکورد راه انداز اصلی یا همان ام.بی.آر ٪1 Boot Partition - + پارتیشن بوت System Partition - + پارتیشن سیستمی Do not install a boot loader - + بوت لودر نصب نکن. %1 (%2) - + %1 (%2) @@ -52,7 +52,7 @@ Blank Page - + صفحه خالی @@ -60,58 +60,58 @@ Form - + فرم GlobalStorage - + ذخیره‌سازی همگانی JobQueue - + صف کارها Modules - + ماژول‌ها Type: - + نوع: none - + هیچ Interface: - + رابط: Tools - + ابزارها Reload Stylesheet - + بارگزاری مجدد برگه‌شیوه Widget Tree - + درخت ابزارک‌ها Debug information - + اطلاعات رفع اشکال @@ -119,12 +119,12 @@ Set up - + راه‌اندازی Install - + نصب @@ -132,12 +132,12 @@ Job failed (%1) - + کار شکست خورد. (%1) Programmed job failure was explicitly requested. - + عدم موفقیت کار برنامه ریزی شده به صورت صریح درخواست شد @@ -145,7 +145,7 @@ Done - + انجام شد. @@ -153,7 +153,7 @@ Example job (%1) - + کار نمونه (%1) @@ -161,17 +161,17 @@ Run command '%1' in target system. - + دستور '%1' را در سیستم هدف اجرا کنید Run command '%1'. - + دستور '%1' را اجرا کنید Running command %1 %2 - + اجرای دستور %1 %2 @@ -179,32 +179,32 @@ Running %1 operation. - + اجرا عملیات %1 Bad working directory path - + مسیر شاخه جاری نامناسب Working directory %1 for python job %2 is not readable. - + شاخه جاری %1 برای کار پایتونی %2 خواندنی نیست Bad main script file - + اسکریپت اصلی مشکل‌دار Main script file %1 for python job %2 is not readable. - + فایل اسکریپت اصلی %1 برای کار پایتون %2 قابل خواندن نیست. Boost.Python error in job "%1". - + Boost.Python error in job "%1". @@ -212,17 +212,17 @@ Loading ... - + در حال بارگذاری ... QML Step <i>%1</i>. - + مرحله QML <i>%1</i>. Loading failed. - + بارگذاری شکست خورد. @@ -230,9 +230,9 @@ Waiting for %n module(s). - - - + + منتظر ماندن برای n% ماژول + منتظر ماندن برای n% ماژول (ها). @@ -246,7 +246,7 @@ System-requirements checking is complete. - + چک کردن نیازمندی‌های سیستم تمام شد. @@ -254,171 +254,173 @@ Setup Failed - + راه‌اندازی شکست خورد. Installation Failed - + نصب شکست خورد. Would you like to paste the install log to the web? - + آیا مایلید که گزارش‌ها در وب الصاق شوند؟ Error - + خطا &Yes - + &بله &No - + &خیر &Close - + &بسته Install Log Paste URL - + Install Log Paste URL The upload was unsuccessful. No web-paste was done. - + The upload was unsuccessful. No web-paste was done. Calamares Initialization Failed - + راه اندازی کالاماریس شکست خورد. %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 نمی‌تواند نصب شود. کالاماریس نمی‌تواند همه ماژول‌های پیکربندی را بالا بیاورد. این یک مشکل در نحوه استفاده کالاماریس توسط توزیع است. <br/>The following modules could not be loaded: - + <br/>این ماژول نمی‌تواند بالا بیاید: Continue with setup? - + راه اندازی ادامه یابد؟ Continue with installation? - + نصب ادامه یابد؟ The %1 setup program is about to make changes to your disk in order to set up %2.<br/><strong>You will not be able to undo these changes.</strong> - + برنامه نصب %1 در شرف ایجاد تغییرات در دیسک شما به منظور راه‌اندازی %2 است. <br/><strong>شما قادر نخواهید بود تا این تغییرات را برگردانید.</strong> The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> - + نصاب %1 در شرف ایجاد تغییرات در دیسک شما به منظور نصب %2 است. <br/><strong>شما قادر نخواهید بود تا این تغییرات را برگردانید.</strong> &Set up now - + &همین حالا راه‌انداری کنید &Install now - + &همین حالا نصب کنید Go &back - + برگردید به &عقب &Set up - + &راه‌اندازی &Install - + &نصب Setup is complete. Close the setup program. - + نصب انجام شد. برنامه نصب را ببندید. The installation is complete. Close the installer. - + نصب انجام شد. نصاب را ببندید. Cancel setup without changing the system. - + لغو راه‌اندازی بدون تغییر سیستم. Cancel installation without changing the system. - + لغو نصب بدون تغییر کردن سیستم. &Next - + &بعدی &Back - + &قبلی &Done - + &انجام شد &Cancel - + &لغو Cancel setup? - + لغو راه‌اندازی؟ Cancel installation? - + لغو نصب؟ Do you really want to cancel the current setup process? The setup program will quit and all changes will be lost. - + آیا واقعا می‌خواهید روند راه‌اندازی فعلی رو لغو کنید؟ +برنامه راه اندازی ترک می شود و همه تغییرات از بین می روند. Do you really want to cancel the current install process? The installer will quit and all changes will be lost. - + آیا واقعاً می خواهید روند نصب فعلی را لغو کنید؟ +نصاب ترک می شود و همه تغییرات از بین می روند. @@ -426,22 +428,22 @@ The installer will quit and all changes will be lost. Unknown exception type - + نوع ناشناخته استثنا unparseable Python error - + unparseable Python error unparseable Python traceback - + unparseable Python traceback Unfetchable Python error. - + Unfetchable Python error. @@ -450,7 +452,8 @@ The installer will quit and all changes will be lost. Install log posted to: %1 - + نصب رخدادهای ارسال شده به: +%1 @@ -458,32 +461,32 @@ The installer will quit and all changes will be lost. Show debug information - + نمایش اطلاعات دیباگ &Back - + &قبلی &Next - + &بعدی &Cancel - + &لغو %1 Setup Program - + %1 برنامه راه‌اندازی %1 Installer - + %1 نصاب @@ -491,7 +494,7 @@ The installer will quit and all changes will be lost. Gathering system information... - + جمع‌آوری اطلاعات سیستم... @@ -499,12 +502,12 @@ The installer will quit and all changes will be lost. Form - + فرم Select storage de&vice: - + انتخاب &دستگاه ذخیره‌سازی: @@ -512,62 +515,62 @@ The installer will quit and all changes will be lost. Current: - + فعلی: After: - + بعد از: <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. Having a GPT partition table and <strong>fat32 512Mb /boot partition is a must for UEFI installs</strong>, either use an existing without formatting or create one. - + <strong>پارتیشن‌بندی دستی</strong><br/>شما می‌توانید خودتان پارتیشن‌ها را بسازید و یا تغییر سایز دهید. با داشتن یک جدول پارتیشن GPT و <strong>پارتیشن /boot با اندازه 512 مگابیتی fat32 برای نصب‌های UEFI الزامی است</strong>، چه با استفاده از نمونه موجود آن بدون قالب‌بندی یا ساخت آن. Reuse %1 as home partition for %2. - + استفاده مجدد از %1 به عنوان پارتیشن خانه برای %2. <strong>Select a partition to shrink, then drag the bottom bar to resize</strong> - + <strong>انتخاب یک پارتیشن برای کوجک کردن و ایجاد پارتیشن جدید از آن، سپس نوار دکمه را بکشید تا تغییر اندازه دهد</strong> %1 will be shrunk to %2MiB and a new %3MiB partition will be created for %4. - + %1 تغییر سایز خواهد داد به %2 مبی‌بایت و یک پارتیشن %3 مبی‌بایتی برای %4 ساخته خواهد شد. Boot loader location: - + مکان بالاآورنده بوت: <strong>Select a partition to install on</strong> - + <strong>یک پارتیشن را برای نصب بر روی آن، انتخاب کنید</strong> An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. - + پارتیشن سیستم ای.اف.آی نمی‌تواند در هیچ جایی از این سیستم یافت شود. لطفا برگردید و از پارتیشن بندی دستی استفاده کنید تا %1 را راه‌اندازی کنید. The EFI system partition at %1 will be used for starting %2. - + پارتیشن سیستم ای.اف.آی در %1 برای شروع %2 استفاده خواهد شد. EFI system partition: - + پارتیشن سیستم ای.اف.آی This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + به نظر می‌رسد در دستگاه ذخیره‌سازی هیچ سیستم‌عاملی وجود ندارد. تمایل به انجام چه کاری دارید؟<br/>شما می‌توانید انتخاب‌هایتان را قبل از اعمال هر تغییری در دستگاه ذخیره‌سازی، مرور و تأیید نمایید. @@ -575,7 +578,7 @@ The installer will quit and all changes will be lost. <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. - + <strong>پاک کردن دیسک</strong><br/>این کار تمام داده‌های موجود بر روی دستگاه ذخیره‌سازی انتخاب شده را <font color="red">حذف می‌کند</font>. @@ -583,7 +586,7 @@ The installer will quit and all changes will be lost. <strong>Install alongside</strong><br/>The installer will shrink a partition to make room for %1. - + <strong>نصب در امتداد</strong><br/>این نصاب از یک پارتیشن برای ساخت یک اتاق برای %1 استفاده می‌کند. @@ -611,7 +614,7 @@ The installer will quit and all changes will be lost. No Swap - + بدون Swap @@ -1097,13 +1100,13 @@ The installer will quit and all changes will be lost. %1 - %2 (%3) device[name] - size[number] (device-node[name]) - + %1 - %2 (%3) %1 - (%2) device[name] - (device-node[name]) - + %1 - (%2) @@ -1111,7 +1114,7 @@ The installer will quit and all changes will be lost. Write LUKS configuration for Dracut to %1 - + Write LUKS configuration for Dracut to %1 @@ -1195,7 +1198,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -1261,7 +1264,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -1543,7 +1546,7 @@ The installer will quit and all changes will be lost. &Cancel - + &لغو @@ -1556,7 +1559,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -2157,7 +2160,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -2198,7 +2201,7 @@ The installer will quit and all changes will be lost. Name - + نام @@ -2211,7 +2214,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -2229,7 +2232,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -2326,43 +2329,43 @@ The installer will quit and all changes will be lost. Root - + ریشه Home - + خانه Boot - + بوت EFI system - + سیستم ای.اف.آی Swap - + Swap New partition for %1 - + پارتیشن جدید برای %1 New partition - + پارتیشن جدید %1 %2 size[number] filesystem[name] - + %1 %2 @@ -2371,23 +2374,23 @@ The installer will quit and all changes will be lost. Free Space - + فضای خالی New partition - + پارتیشن جدید Name - + نام File System - + سیستم فایل @@ -2405,7 +2408,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -2483,32 +2486,32 @@ The installer will quit and all changes will be lost. Gathering system information... - + جمع‌آوری اطلاعات سیستم... Partitions - + پارتیشن‌ها Install %1 <strong>alongside</strong> another operating system. - + نصب %1 <strong>در امتداد</strong> سیستم عامل دیگر. <strong>Erase</strong> disk and install %1. - + <strong>پاک کردن</strong> دیسک و نصب %1. <strong>Replace</strong> a partition with %1. - + <strong>جایگزینی</strong> یک پارتیشن و با %1 <strong>Manual</strong> partitioning. - + <strong>پارتیشن‌بندی</strong> دستی. @@ -2538,12 +2541,12 @@ The installer will quit and all changes will be lost. Current: - + فعلی: After: - + بعد از: @@ -2578,7 +2581,7 @@ The installer will quit and all changes will be lost. Boot partition not encrypted - + پارتیشن بوت رمزشده نیست @@ -2593,7 +2596,7 @@ The installer will quit and all changes will be lost. There are no partitions to install on. - + هیچ پارتیشنی برای نصب وجود ندارد @@ -2615,7 +2618,7 @@ The installer will quit and all changes will be lost. Form - + فرم @@ -2667,7 +2670,7 @@ There was no output from the command. Output: - + خروجی @@ -2725,7 +2728,7 @@ Output: %1 (%2) - + %1 (%2) @@ -2834,7 +2837,7 @@ Output: Form - + فرم @@ -2896,12 +2899,12 @@ Output: The EFI system partition at %1 will be used for starting %2. - + پارتیشن سیستم ای.اف.آی در %1 برای شروع %2 استفاده خواهد شد. EFI system partition: - + پارتیشن سیستم ای.اف.آی @@ -3396,7 +3399,7 @@ Output: Form - + فرم @@ -3569,7 +3572,7 @@ Output: Form - + فرم diff --git a/lang/calamares_zh_CN.ts b/lang/calamares_zh_CN.ts index 44fcb8272..7467aa120 100644 --- a/lang/calamares_zh_CN.ts +++ b/lang/calamares_zh_CN.ts @@ -2558,12 +2558,12 @@ The installer will quit and all changes will be lost. An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a FAT32 filesystem with the <strong>%3</strong> flag enabled and mount point <strong>%2</strong>.<br/><br/>You can continue without setting up an EFI system partition but your system may fail to start. - + 必须有 EFI 系统分区才能启动 %1 。<br/><br/>要配置 EFI 系统分区,后退一步,然后创建或选中一个 FAT32 分区并为之设置 <strong>%3</strong> 标记及挂载点 <strong>%2</strong>。<br/><br/>你可以不创建 EFI 系统分区并继续安装,但是你的系统可能无法启动。 An EFI system partition is necessary to start %1.<br/><br/>A partition was configured with mount point <strong>%2</strong> but its <strong>%3</strong> flag is not set.<br/>To set the flag, go back and edit the partition.<br/><br/>You can continue without setting the flag but your system may fail to start. - + 必须有 EFI 系统分区才能启动 %1 。<br/><br/>已有挂载点为 <strong>%2</strong> 的分区,但是未设置 <strong>%3</strong> 标记。<br/>要设置此标记,后退并编辑分区。<br/><br/>你可以不创建 EFI 系统分区并继续安装,但是你的系统可能无法启动。 @@ -3804,7 +3804,28 @@ Output: </ul> <p>The vertical scrollbar is adjustable, current width set to 10.</p> - + <h3>%1</h3> + <p>这是一个QML 示例文件,显示了具有 Flickable 内容的 RichText 选项。</p> + + <p>带有 RichText 的 QML 可以使用 HTML 标签, + Flickable 内容对于触摸屏很有用。</p> + + <p><b>这是粗体字</b></p> + <p><i>这是斜体字</i></p> + <p><u>这是带下划线的文字</u></p> + <p><center>此文本将居中对齐。</center></p> + <p><s>这是删除线</s></p> + + <p>代码示例: + <code>ls -l /home</code></p> + + <p><b>列表:</b></p> + <ul> + <li>Intel CPU 系统</li> + <li>AMD CPU 系统</li> + </ul> + + <p>垂直滚动条是可调的,当前宽度设置为10。</p> @@ -3818,7 +3839,8 @@ Output: <h3>Welcome to the %1 <quote>%2</quote> installer</h3> <p>This program will ask you some questions and set up %1 on your computer.</p> - + <h3>欢迎来到 %1 <quote>%2</quote> 安装程序</h3> + <p>这个程序将询问您一些问题并在您的计算机上安装 %1。</p> From 03a7d1253cc1c04de49eae275235076143d37b0c Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Thu, 14 May 2020 23:52:59 +0200 Subject: [PATCH 23/38] i18n: [python] Automatic merge of Transifex translations --- lang/python/fi_FI/LC_MESSAGES/python.mo | Bin 7920 -> 7918 bytes lang/python/fi_FI/LC_MESSAGES/python.po | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/python/fi_FI/LC_MESSAGES/python.mo b/lang/python/fi_FI/LC_MESSAGES/python.mo index 6ed36a933f358678176f4459e80b9a25c2a3fbe2..9f9791235b0b93e259b6465156d39236d83b1d5b 100644 GIT binary patch delta 307 zcmXBNI}3qf6u|N0Hc=9Czh4FsC0R(X1*P81Cb3vdn3UP5EGC0p>h&3v!R8CtCCUfz ze|qcb`JHn*mrwKEJkM=ww}=daB3>L}1{YYwJ(lo_75t&<&xJ&IQsdK5$24xSffv;A zi)xP+Hs@!k_8m~&xrb#f3Drm;j-H5V1%2c?mT`hh+@T+xQS)#LTjXQx;t{L(!XYMO t%;E|Q_{2QAIHvYg;{lNlL61Tmx0uD7v9UkA*6G|B1^X6D(l~|Mjz7BuC1d~q delta 309 zcmXBNF>At56o%mws$(k>#U$1gl43y&7NxjUN_9|BkjxIH)O2uikh+<vWIj}9*J5x;SWf2eXgRx&?DmA6K<=V(bNH|iq|8}(vh9dpz^*6 Date: Fri, 15 May 2020 12:21:10 +0200 Subject: [PATCH 24/38] [fstab] Add some discussion about *discard* option - drop the *discard* from filesystems-on-SSD in the standard example configuration. - keep the table **with** *discard* around for referece and explanation. Remember that the example configurations are intended as **examples**, to document available settings, and do not reflect a sensible production configuration. FIXES #1395 --- src/modules/fstab/fstab.conf | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/modules/fstab/fstab.conf b/src/modules/fstab/fstab.conf index b2f3de361..ce38a184c 100644 --- a/src/modules/fstab/fstab.conf +++ b/src/modules/fstab/fstab.conf @@ -20,12 +20,25 @@ efiMountOptions: umask=0077 # If a filesystem is on an SSD, add the following options. If a specific # filesystem is listed here, use those options, otherwise no additional # options are set (i.e. there is no *default* like in *mountOptions*). +# +# This example configuration applies the *discard* option to most +# common filesystems on an SSD. This may not be the right option +# for your distribution. If you use a systemd timer to trim the +# SSD, it may interfere with the *discard* option. Opinions vary +# as to whether *discard* is worth the effort -- it depends on +# the usage pattern of the disk as well. +# +# ssdExtraMountOptions: +# ext4: discard +# jfs: discard +# xfs: discard +# swap: discard +# btrfs: discard,compress=lzo +# +# The standard configuration applies only lzo compression to btrfs +# and does nothing for other filesystems. ssdExtraMountOptions: - ext4: discard - jfs: discard - xfs: discard - swap: discard - btrfs: discard,compress=lzo + btrfs: compress=lzo # Additional options added to each line in /etc/crypttab crypttabOptions: luks From c3d8112187255d24eaeb0d579e52b13e3df659fd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 15 May 2020 14:38:45 +0200 Subject: [PATCH 25/38] CMake: allow fine-tuning tests - The Python configuration tests sometimes need extra setup, so do that through a CMakeTests.txt file in the test directory. - Patch up existing tests: - grubcfg needs /tmp/calamares/etc/default to exist - rawfs won't work on FreeBSD because of differences in /proc --- CHANGES | 2 ++ .../CalamaresAddModuleSubdirectory.cmake | 19 ++++++++++++++++--- src/modules/grubcfg/tests/CMakeTests.txt | 12 ++++++++++++ src/modules/rawfs/tests/CMakeTests.txt | 8 ++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/modules/grubcfg/tests/CMakeTests.txt create mode 100644 src/modules/rawfs/tests/CMakeTests.txt diff --git a/CHANGES b/CHANGES index 0e8221bf0..ee9d29770 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,8 @@ This release contains contributions from (alphabetically by first name): QML-based modules -- with a single `-DWITH_QML=OFF` at CMake time. This removes QML from Calamares' dependency footprint (but only saves 200kB in Calamares itself). + - Tests have been extended and now support a tests/CMakeTests.txt file + for fine-tuning tests for Python modules. ## Modules ## - No module changes yet diff --git a/CMakeModules/CalamaresAddModuleSubdirectory.cmake b/CMakeModules/CalamaresAddModuleSubdirectory.cmake index 1af520ca8..981ec4a01 100644 --- a/CMakeModules/CalamaresAddModuleSubdirectory.cmake +++ b/CMakeModules/CalamaresAddModuleSubdirectory.cmake @@ -126,10 +126,10 @@ function( calamares_add_module_subdirectory ) endif() message( "" ) # We copy over the lang directory, if any - if( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/lang" ) + if( IS_DIRECTORY "${_mod_dir}/lang" ) install_calamares_gettext_translations( ${SUBDIRECTORY} - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/lang" + SOURCE_DIR "${_mod_dir}/lang" FILENAME ${SUBDIRECTORY}.mo RENAME calamares-${SUBDIRECTORY}.mo ) @@ -162,6 +162,16 @@ function( calamares_add_module_subdirectory ) # may try to do things to the running system. Needs work to make that a # safe thing to do. # + # If the module has a tests/ subdirectory with *.global and *.job + # files (YAML files holding global and job-configurations for + # testing purposes) then those files are used to drive additional + # tests. The files must be numbered (starting from 1) for this to work; + # 1.global and 1.job together make the configuration for test 1. + # + # If the module has a tests/CMakeLists.txt while it doesn't have its + # own CMakeLists.txt (e.g. a Python module), then the subdirectory + # for tests/ is added on its own. + # if ( BUILD_TESTING AND _mod_enabled AND _mod_testing ) add_test( NAME load-${SUBDIRECTORY} @@ -170,7 +180,7 @@ function( calamares_add_module_subdirectory ) ) # Try it with the tests/ configurations shipped with the module set( _count 1 ) - set( _testdir ${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/tests ) + set( _testdir ${_mod_dir}/tests ) while ( EXISTS "${_testdir}/${_count}.global" OR EXISTS "${_testdir}/${_count}.job" ) set( _dash_g "" ) set( _dash_j "" ) @@ -187,5 +197,8 @@ function( calamares_add_module_subdirectory ) ) math( EXPR _count "${_count} + 1" ) endwhile() + if ( EXISTS ${_testdir}/CMakeTests.txt AND NOT EXISTS ${_mod_dir}/CMakeLists.txt ) + include( ${_testdir}/CMakeTests.txt ) + endif() endif() endfunction() diff --git a/src/modules/grubcfg/tests/CMakeTests.txt b/src/modules/grubcfg/tests/CMakeTests.txt new file mode 100644 index 000000000..299fccf07 --- /dev/null +++ b/src/modules/grubcfg/tests/CMakeTests.txt @@ -0,0 +1,12 @@ +# Special cases for grubcfg configuration tests: +# - 2.global specifies /tmp/calamares as the rootMountPath, +# so we end up editing files there. Create the directory +# beforehand, so the test doesn't blow up. +set(_grub_root /tmp/calamares/etc/default) +set(_grub_file ${_grub_root}/bogus) + +add_test( + NAME make-grubcfg-dirs + COMMAND ${CMAKE_COMMAND} -E make_directory ${_grub_root} + ) +set_tests_properties(load-grubcfg-2 PROPERTIES DEPENDS make-grubcfg-dirs) diff --git a/src/modules/rawfs/tests/CMakeTests.txt b/src/modules/rawfs/tests/CMakeTests.txt new file mode 100644 index 000000000..44a7777c8 --- /dev/null +++ b/src/modules/rawfs/tests/CMakeTests.txt @@ -0,0 +1,8 @@ +# Special cases for rawfs tests +# +# - On FreeBSD, /proc/mounts doesn't exist (/proc is only about processes, +# and is rarely used). Expect the test to fail. + +if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + set_tests_properties(load-rawfs-1 PROPERTIES WILL_FAIL TRUE) +endif() From 33f6bd56998027dbaf00cab400d30cb5ada70c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Thu, 14 May 2020 09:08:17 -0400 Subject: [PATCH 26/38] [bootloader] Remove unused variable root_mount_point - root_mount_point was used initially for logging c1a139995 (adding new bootloader job options are to use grub for BIOS, gummiboot for efi set extra mountpoint when efi is found) - the trace was removed since 533031b3c ([bootloader] print() does not log) --- src/modules/bootloader/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index 674484527..87288b583 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -57,7 +57,6 @@ def get_uuid(): :return: """ - root_mount_point = libcalamares.globalstorage.value("rootMountPoint") partitions = libcalamares.globalstorage.value("partitions") for partition in partitions: From 7e83296aa25628494f17c7ba483470b852367fde Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 15 May 2020 22:00:20 +0200 Subject: [PATCH 27/38] Changes: name contributors so far this release --- CHANGES | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index ee9d29770..61d003f1c 100644 --- a/CHANGES +++ b/CHANGES @@ -6,7 +6,9 @@ website will have to do for older versions. # 3.2.25 (unreleased) # This release contains contributions from (alphabetically by first name): - - No external contributors yet + - Anke Boersma + - FLVAL + - Gaël PORTAY ## Core ## - The slideshow in `branding.desc` can be configured with QML (recommended, From e2c99eeb5e7c889d83ba4eea6a070141550133b2 Mon Sep 17 00:00:00 2001 From: demmm Date: Sun, 17 May 2020 12:37:01 +0200 Subject: [PATCH 28/38] [welcomeq] adjust spacing make sure the listviews fit in the default window size without overlapping the language bar --- src/modules/welcomeq/Recommended.qml | 10 +++++----- src/modules/welcomeq/Requirements.qml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/modules/welcomeq/Recommended.qml b/src/modules/welcomeq/Recommended.qml index 7144cbd9a..636311b11 100644 --- a/src/modules/welcomeq/Recommended.qml +++ b/src/modules/welcomeq/Recommended.qml @@ -29,13 +29,13 @@ Rectangle { focus: true Kirigami.Theme.backgroundColor: Kirigami.Theme.backgroundColor anchors.fill: parent - anchors.topMargin: 70 + anchors.topMargin: 50 TextArea { id: recommended anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - anchors.topMargin: 10 + anchors.topMargin: 1 horizontalAlignment: TextEdit.AlignHCenter width: 640 font.pointSize: 11 @@ -50,7 +50,7 @@ Rectangle { Rectangle { width: 640 - height: 400 + height: 360 anchors.horizontalCenter: parent.horizontalCenter anchors.top: recommended.bottom anchors.topMargin: 5 @@ -60,14 +60,14 @@ Rectangle { Item { width: 640 - height: 40 + height: 35 Column { anchors.centerIn: parent Rectangle { implicitWidth: 640 - implicitHeight: 40 + implicitHeight: 35 border.color: satisfied ? "#228b22" : "#ffa411" color: satisfied ? "#f0fff0" : "#ffefd5" diff --git a/src/modules/welcomeq/Requirements.qml b/src/modules/welcomeq/Requirements.qml index 00a045041..e81d0a2e6 100644 --- a/src/modules/welcomeq/Requirements.qml +++ b/src/modules/welcomeq/Requirements.qml @@ -29,13 +29,13 @@ Rectangle { focus: true Kirigami.Theme.backgroundColor: Kirigami.Theme.backgroundColor anchors.fill: parent - anchors.topMargin: 70 + anchors.topMargin: 50 TextArea { id: required anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - anchors.topMargin: 10 + anchors.topMargin: 1 horizontalAlignment: TextEdit.AlignHCenter width: 640 font.pointSize: 11 @@ -50,7 +50,7 @@ Rectangle { Rectangle { width: 640 - height: 400 + height: 360 anchors.horizontalCenter: parent.horizontalCenter anchors.top: required.bottom anchors.topMargin: 5 @@ -60,14 +60,14 @@ Rectangle { Item { width: 640 - height: 40 + height: 35 Column { anchors.centerIn: parent Rectangle { implicitWidth: 640 - implicitHeight: 40 + implicitHeight: 35 border.color: mandatory ? "#228b22" : "#ff0000" color: mandatory ? "#f0fff0" : "#ffc0cb" From c6671f9495b963be341c5f36fc4ae7265c386c8e Mon Sep 17 00:00:00 2001 From: demmm Date: Sun, 17 May 2020 12:41:22 +0200 Subject: [PATCH 29/38] Changes: welcomeq is now a functional module --- CHANGES | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 61d003f1c..2bf44c8a9 100644 --- a/CHANGES +++ b/CHANGES @@ -22,8 +22,12 @@ This release contains contributions from (alphabetically by first name): for fine-tuning tests for Python modules. ## Modules ## - - No module changes yet - + - The QML based *welcomeq* module is now a viable alternative to the + *welcome*(widgets based) module. Using QML files means it no longer + is needed to have pop-up windows for additional information or warnings, + all loads in the Calamares window itself. Additional features include the + option to customize the *About* info and load files like Release Notes + direct into Calamares, QML files added to the branding directory can be used. # 3.2.24 (2020-05-11) # From 27d4fa675b8e76f4262955468012e9febd8a4d0b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 29 Apr 2020 21:57:10 +0200 Subject: [PATCH 30/38] [locale] remove unneeded this-> --- src/modules/locale/Config.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/locale/Config.cpp b/src/modules/locale/Config.cpp index ea1dc5423..cde0a5e09 100644 --- a/src/modules/locale/Config.cpp +++ b/src/modules/locale/Config.cpp @@ -81,16 +81,16 @@ Config::setLocaleInfo( const QString& initialRegion, const QString& initialZone, auto* region = m_regionList.find< TZRegion >( initialRegion ); if ( region && region->zones().find< TZZone >( initialZone ) ) { - this->m_regionModel->setCurrentIndex( m_regionModel->indexOf( initialRegion ) ); + m_regionModel->setCurrentIndex( m_regionModel->indexOf( initialRegion ) ); m_zonesModel->setList( region->zones() ); - this->m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( initialZone ) ); + m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( initialZone ) ); } else { - this->m_regionModel->setCurrentIndex( m_regionModel->indexOf( "America" ) ); + m_regionModel->setCurrentIndex( m_regionModel->indexOf( "America" ) ); m_zonesModel->setList( static_cast< const TZRegion* >( m_regionModel->item( m_regionModel->currentIndex() ) )->zones() ); - this->m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( "New_York" ) ); + m_zonesModel->setCurrentIndex( m_zonesModel->indexOf( "New_York" ) ); } // Some distros come with a meaningfully commented and easy to parse locale.gen, From 4c0a212b688d96d3b44835b0d898212987771b0b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 10:12:12 +0200 Subject: [PATCH 31/38] [partition] Warnings-- (Qt 5.14) QVariant::fromValue doesn't have *since* documentation, so I expect it to be 5.6-and-later. --- src/modules/partition/core/PartitionModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionModel.cpp b/src/modules/partition/core/PartitionModel.cpp index d6f996c4f..1135f5719 100644 --- a/src/modules/partition/core/PartitionModel.cpp +++ b/src/modules/partition/core/PartitionModel.cpp @@ -241,7 +241,7 @@ PartitionModel::data( const QModelIndex& index, int role ) const return partition->partitionPath(); case PartitionPtrRole: - return qVariantFromValue( (void*)partition ); + return QVariant::fromValue( (void*)partition ); // Osprober roles: case OsproberNameRole: From f67d8ef162ae0e32fb02b0f067ebcda0c67269dd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 10:25:19 +0200 Subject: [PATCH 32/38] [3rdparty] Chase API deprecation in Qt - QElapsedTimer has existed since Qt 4.7 --- 3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp b/3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp index 4c13e1da0..cd8fadcce 100644 --- a/3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp +++ b/3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -764,7 +765,7 @@ void KDSingleApplicationGuard::Private::create( const QStringList & arguments ) } const int maxWaitMSecs = 1000 * 60; // stop waiting after 60 seconds - QTime waitTimer; + QElapsedTimer waitTimer; waitTimer.start(); // lets wait till the other instance initialized the register From 8d4c7767d450a4c03f81abd7131181ea8d29ba19 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 10:32:25 +0200 Subject: [PATCH 33/38] [libcalamaresui] Document ClickableLabel --- src/libcalamaresui/widgets/ClickableLabel.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libcalamaresui/widgets/ClickableLabel.h b/src/libcalamaresui/widgets/ClickableLabel.h index fd66082c5..5a3265c13 100644 --- a/src/libcalamaresui/widgets/ClickableLabel.h +++ b/src/libcalamaresui/widgets/ClickableLabel.h @@ -17,12 +17,19 @@ * along with Calamares. If not, see . */ -#ifndef CLICKABLELABEL_H -#define CLICKABLELABEL_H +#ifndef LIBCALAMARESUI_CLICKABLELABEL_H +#define LIBCALAMARESUI_CLICKABLELABEL_H #include -#include +#include +/** @brief A Label where the whole label area is clickable + * + * When clicking anywhere on the Label (text, background, whatever) + * the signal clicked() is emitted. Use this as a buddy for radio + * buttons or other clickable things where you want mouse interaction + * with the label, to be the same as mouse interaction with the control. + */ class ClickableLabel : public QLabel { Q_OBJECT @@ -39,7 +46,7 @@ protected: virtual void mouseReleaseEvent( QMouseEvent* event ) override; private: - QTime m_time; + QElapsedTimer m_time; }; -#endif // CLICKABLELABEL_H +#endif // LIBCALAMARESUI_CLICKABLELABEL_H From c4951d5090795c64d05e108febc42899d2fa8084 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 10:38:45 +0200 Subject: [PATCH 34/38] [libcalamaresui] Move PrettyRadioButton from partition --- src/libcalamaresui/CMakeLists.txt | 1 + .../gui => libcalamaresui/widgets}/PrettyRadioButton.cpp | 0 .../gui => libcalamaresui/widgets}/PrettyRadioButton.h | 6 +++--- src/modules/partition/CMakeLists.txt | 1 - 4 files changed, 4 insertions(+), 4 deletions(-) rename src/{modules/partition/gui => libcalamaresui/widgets}/PrettyRadioButton.cpp (100%) rename src/{modules/partition/gui => libcalamaresui/widgets}/PrettyRadioButton.h (93%) diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index c5c7e9d4b..32fec2cb1 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -22,6 +22,7 @@ set( calamaresui_SOURCES widgets/ClickableLabel.cpp widgets/FixedAspectRatioLabel.cpp + widgets/PrettyRadioButton.cpp widgets/WaitingWidget.cpp ${CMAKE_SOURCE_DIR}/3rdparty/waitingspinnerwidget.cpp diff --git a/src/modules/partition/gui/PrettyRadioButton.cpp b/src/libcalamaresui/widgets/PrettyRadioButton.cpp similarity index 100% rename from src/modules/partition/gui/PrettyRadioButton.cpp rename to src/libcalamaresui/widgets/PrettyRadioButton.cpp diff --git a/src/modules/partition/gui/PrettyRadioButton.h b/src/libcalamaresui/widgets/PrettyRadioButton.h similarity index 93% rename from src/modules/partition/gui/PrettyRadioButton.h rename to src/libcalamaresui/widgets/PrettyRadioButton.h index c88c00728..efc4be70c 100644 --- a/src/modules/partition/gui/PrettyRadioButton.h +++ b/src/libcalamaresui/widgets/PrettyRadioButton.h @@ -16,8 +16,8 @@ * along with Calamares. If not, see . */ -#ifndef PRETTYRADIOBUTTON_H -#define PRETTYRADIOBUTTON_H +#ifndef LIBCALAMARESUI_PRETTYRADIOBUTTON_H +#define LIBCALAMARESUI_PRETTYRADIOBUTTON_H #include @@ -64,4 +64,4 @@ protected: QHBoxLayout* m_optionsLayout; }; -#endif // PRETTYRADIOBUTTON_H +#endif // LIBCALAMARESUI_PRETTYRADIOBUTTON_H diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index d01a7d983..d40bbcd1c 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -80,7 +80,6 @@ if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND gui/PartitionSizeController.cpp gui/PartitionSplitterWidget.cpp gui/PartitionViewStep.cpp - gui/PrettyRadioButton.cpp gui/ResizeVolumeGroupDialog.cpp gui/ScanningDialog.cpp gui/ReplaceWidget.cpp From 3b7c3c4f5dca54a69f190d1e9950a0547b1df4d8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 10:53:23 +0200 Subject: [PATCH 35/38] [libcalamaresui] Coding style - Apply coding style - Place the widget classes in namespace Calamares - Export symbols for widgets --- src/libcalamaresui/widgets/ClickableLabel.cpp | 7 ++++++- src/libcalamaresui/widgets/ClickableLabel.h | 11 +++++++++-- src/libcalamaresui/widgets/PrettyRadioButton.cpp | 16 +++++++++++----- src/libcalamaresui/widgets/PrettyRadioButton.h | 14 ++++++++++---- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/libcalamaresui/widgets/ClickableLabel.cpp b/src/libcalamaresui/widgets/ClickableLabel.cpp index 6e6f54459..8f2323fa4 100644 --- a/src/libcalamaresui/widgets/ClickableLabel.cpp +++ b/src/libcalamaresui/widgets/ClickableLabel.cpp @@ -18,7 +18,10 @@ #include "ClickableLabel.h" -#include +#include // for doubleClickInterval() + +namespace Calamares +{ ClickableLabel::ClickableLabel( QWidget* parent ) @@ -53,3 +56,5 @@ ClickableLabel::mouseReleaseEvent( QMouseEvent* event ) emit clicked(); } } + +} // namespace Calamares diff --git a/src/libcalamaresui/widgets/ClickableLabel.h b/src/libcalamaresui/widgets/ClickableLabel.h index 5a3265c13..f60a247ca 100644 --- a/src/libcalamaresui/widgets/ClickableLabel.h +++ b/src/libcalamaresui/widgets/ClickableLabel.h @@ -20,8 +20,13 @@ #ifndef LIBCALAMARESUI_CLICKABLELABEL_H #define LIBCALAMARESUI_CLICKABLELABEL_H -#include #include +#include + +#include "DllMacro.h" + +namespace Calamares +{ /** @brief A Label where the whole label area is clickable * @@ -30,7 +35,7 @@ * buttons or other clickable things where you want mouse interaction * with the label, to be the same as mouse interaction with the control. */ -class ClickableLabel : public QLabel +class UIDLLEXPORT ClickableLabel : public QLabel { Q_OBJECT public: @@ -49,4 +54,6 @@ private: QElapsedTimer m_time; }; +} // namespace Calamares + #endif // LIBCALAMARESUI_CLICKABLELABEL_H diff --git a/src/libcalamaresui/widgets/PrettyRadioButton.cpp b/src/libcalamaresui/widgets/PrettyRadioButton.cpp index 18627f41c..31b74e9e2 100644 --- a/src/libcalamaresui/widgets/PrettyRadioButton.cpp +++ b/src/libcalamaresui/widgets/PrettyRadioButton.cpp @@ -26,6 +26,8 @@ #include #include +namespace Calamares +{ PrettyRadioButton::PrettyRadioButton( QWidget* parent ) : QWidget( parent ) @@ -45,10 +47,8 @@ PrettyRadioButton::PrettyRadioButton( QWidget* parent ) m_mainLayout->addWidget( m_label, 0, 1 ); m_mainLayout->setContentsMargins( 0, 0, 0, 0 ); - connect( m_label, &ClickableLabel::clicked, - m_radio, &QRadioButton::click ); - connect( m_radio, &QRadioButton::toggled, - this, &PrettyRadioButton::toggleOptions ); + connect( m_label, &ClickableLabel::clicked, m_radio, &QRadioButton::click ); + connect( m_radio, &QRadioButton::toggled, this, &PrettyRadioButton::toggleOptions ); } @@ -90,7 +90,9 @@ void PrettyRadioButton::addOptionsComboBox( QComboBox* box ) { if ( !box ) + { return; + } if ( !m_optionsLayout ) { @@ -105,12 +107,16 @@ PrettyRadioButton::addOptionsComboBox( QComboBox* box ) toggleOptions( m_radio->isChecked() ); } - m_optionsLayout->insertWidget( m_optionsLayout->count()-1, box ); + m_optionsLayout->insertWidget( m_optionsLayout->count() - 1, box ); } void PrettyRadioButton::toggleOptions( bool toggle ) { if ( m_optionsLayout ) + { m_optionsLayout->parentWidget()->setVisible( toggle ); + } } + +} // namespace Calamares diff --git a/src/libcalamaresui/widgets/PrettyRadioButton.h b/src/libcalamaresui/widgets/PrettyRadioButton.h index efc4be70c..dbaa88707 100644 --- a/src/libcalamaresui/widgets/PrettyRadioButton.h +++ b/src/libcalamaresui/widgets/PrettyRadioButton.h @@ -19,13 +19,18 @@ #ifndef LIBCALAMARESUI_PRETTYRADIOBUTTON_H #define LIBCALAMARESUI_PRETTYRADIOBUTTON_H +#include "DllMacro.h" + #include -class ClickableLabel; class QComboBox; class QGridLayout; class QHBoxLayout; +namespace Calamares +{ +class ClickableLabel; + /** @brief A radio button with fancy label next to it. * * The radio button itself can be retrieved with buttonWidget(), @@ -33,12 +38,12 @@ class QHBoxLayout; * added to the display (options are hidden when the button is * not selected) with addOptionsComboBox(). */ -class PrettyRadioButton : public QWidget +class UIDLLEXPORT PrettyRadioButton : public QWidget { Q_OBJECT public: explicit PrettyRadioButton( QWidget* parent = nullptr ); - virtual ~PrettyRadioButton() {} + virtual ~PrettyRadioButton() { } virtual void setText( const QString& text ); @@ -64,4 +69,5 @@ protected: QHBoxLayout* m_optionsLayout; }; -#endif // LIBCALAMARESUI_PRETTYRADIOBUTTON_H +} // namespace Calamares +#endif // LIBCALAMARESUI_PRETTYRADIOBUTTON_H From 17231ae41f5c5ba8d08618ab2d1f83ed868508b9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 11:17:36 +0200 Subject: [PATCH 36/38] [libcalamaresui] Sanitize API of PrettyRadioButton - Don't expose internals - Drop unnecessary virtual - Offer new API to do the things, for which internals were exposed --- .../widgets/PrettyRadioButton.cpp | 21 ++++++++++++--- .../widgets/PrettyRadioButton.h | 27 ++++++++++++++----- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/libcalamaresui/widgets/PrettyRadioButton.cpp b/src/libcalamaresui/widgets/PrettyRadioButton.cpp index 31b74e9e2..1cf348315 100644 --- a/src/libcalamaresui/widgets/PrettyRadioButton.cpp +++ b/src/libcalamaresui/widgets/PrettyRadioButton.cpp @@ -21,6 +21,7 @@ #include "utils/CalamaresUtilsGui.h" #include "widgets/ClickableLabel.h" +#include #include #include #include @@ -80,12 +81,26 @@ PrettyRadioButton::iconSize() const } -QRadioButton* -PrettyRadioButton::buttonWidget() const +void +PrettyRadioButton::setChecked( bool checked ) { - return m_radio; + m_radio->setChecked( checked ); } + +bool +PrettyRadioButton::isChecked() const +{ + return m_radio->isChecked(); +} + +void +PrettyRadioButton::addToGroup( QButtonGroup* group, int id ) +{ + group->addButton( m_radio, id ); +} + + void PrettyRadioButton::addOptionsComboBox( QComboBox* box ) { diff --git a/src/libcalamaresui/widgets/PrettyRadioButton.h b/src/libcalamaresui/widgets/PrettyRadioButton.h index dbaa88707..9c7139526 100644 --- a/src/libcalamaresui/widgets/PrettyRadioButton.h +++ b/src/libcalamaresui/widgets/PrettyRadioButton.h @@ -23,6 +23,7 @@ #include +class QButtonGroup; class QComboBox; class QGridLayout; class QHBoxLayout; @@ -32,6 +33,9 @@ namespace Calamares class ClickableLabel; /** @brief A radio button with fancy label next to it. + * + * The fancy label is used so that the text alongside the radio + * button can word-wrap, be multi-line, and support rich text. * * The radio button itself can be retrieved with buttonWidget(), * and the whole behaves a lot like a label. Extra options can be @@ -45,17 +49,26 @@ public: explicit PrettyRadioButton( QWidget* parent = nullptr ); virtual ~PrettyRadioButton() { } - virtual void setText( const QString& text ); + /// @brief Passes @p text on to the ClickableLabel + void setText( const QString& text ); - virtual void setIconSize( const QSize& size ); + // Icon applies to the radio-button part + void setIconSize( const QSize& size ); + QSize iconSize() const; + void setIcon( const QIcon& icon ); - virtual void setIcon( const QIcon& icon ); + // Applies to the radio-button part + void setChecked( bool checked ); + bool isChecked() const; - virtual QSize iconSize() const; + /** @brief Adds the radio-button part to the given @p group + * + * For managing the pretty-radio-button in button groups like normal + * radio buttons, call addToGroup() rather that group->addButton(). + */ + void addToGroup( QButtonGroup* group, int id = -1 ); - virtual QRadioButton* buttonWidget() const; - - /** @brief Add an options drop-down to this button. */ + /// @brief Add an options drop-down to this button. void addOptionsComboBox( QComboBox* ); protected slots: From 72857b75d01a4ddca7b3abdbfb0088dcbf638709 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 11:01:54 +0200 Subject: [PATCH 37/38] [partition] Chase moving PrettyRadioButton to libcalamaresui - Update includes - Use exposed API instead of accessing internals of the button --- src/modules/partition/gui/ChoicePage.cpp | 22 +++++++++++----------- src/modules/partition/gui/ChoicePage.h | 18 +++++++++++------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index c69768f70..5c90ea7b0 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -35,20 +35,19 @@ #include "PartitionBarsView.h" #include "PartitionLabelsView.h" #include "PartitionSplitterWidget.h" -#include "PrettyRadioButton.h" #include "ReplaceWidget.h" #include "ScanningDialog.h" +#include "Branding.h" #include "GlobalStorage.h" #include "JobQueue.h" #include "partition/PartitionIterator.h" #include "partition/PartitionQuery.h" +#include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" #include "utils/Retranslator.h" #include "utils/Units.h" - -#include "Branding.h" -#include "utils/CalamaresUtilsGui.h" +#include "widgets/PrettyRadioButton.h" #include #include @@ -69,6 +68,7 @@ using PartitionActions::Choices::SwapChoice; using CalamaresUtils::Partition::PartitionIterator; using CalamaresUtils::Partition::isPartitionFreeSpace; using CalamaresUtils::Partition::findPartitionByPath; +using Calamares::PrettyRadioButton; /** @brief Given a set of swap choices, return a sensible value from it. * @@ -259,14 +259,14 @@ ChoicePage::setupChoices() m_alongsideButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionAlongside, CalamaresUtils::Original, iconSize ) ); - m_grp->addButton( m_alongsideButton->buttonWidget(), Alongside ); + m_alongsideButton->addToGroup( m_grp, Alongside ); m_eraseButton = new PrettyRadioButton; m_eraseButton->setIconSize( iconSize ); m_eraseButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionEraseAuto, CalamaresUtils::Original, iconSize ) ); - m_grp->addButton( m_eraseButton->buttonWidget(), Erase ); + m_eraseButton->addToGroup( m_grp, Erase ); m_replaceButton = new PrettyRadioButton; @@ -274,7 +274,7 @@ ChoicePage::setupChoices() m_replaceButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionReplaceOs, CalamaresUtils::Original, iconSize ) ); - m_grp->addButton( m_replaceButton->buttonWidget(), Replace ); + m_replaceButton->addToGroup( m_grp, Replace ); // Fill up swap options // .. TODO: only if enabled in the config @@ -294,7 +294,7 @@ ChoicePage::setupChoices() CalamaresUtils::Original, iconSize ) ); m_itemsLayout->addWidget( m_somethingElseButton ); - m_grp->addButton( m_somethingElseButton->buttonWidget(), Manual ); + m_somethingElseButton->addToGroup( m_grp, Manual ); m_itemsLayout->addStretch(); @@ -1193,7 +1193,7 @@ force_uncheck(QButtonGroup* grp, PrettyRadioButton* button) { button->hide(); grp->setExclusive( false ); - button->buttonWidget()->setChecked( false ); + button->setChecked( false ); grp->setExclusive( true ); } @@ -1288,8 +1288,8 @@ ChoicePage::setupActions() m_replaceButton->hide(); m_alongsideButton->hide(); m_grp->setExclusive( false ); - m_replaceButton->buttonWidget()->setChecked( false ); - m_alongsideButton->buttonWidget()->setChecked( false ); + m_replaceButton->setChecked( false ); + m_alongsideButton->setChecked( false ); m_grp->setExclusive( true ); } else if ( osproberEntriesForCurrentDevice.count() == 1 ) diff --git a/src/modules/partition/gui/ChoicePage.h b/src/modules/partition/gui/ChoicePage.h index baf575d49..1ff8f0d40 100644 --- a/src/modules/partition/gui/ChoicePage.h +++ b/src/modules/partition/gui/ChoicePage.h @@ -23,7 +23,6 @@ #include "ui_ChoicePage.h" -#include #include "core/OsproberEntry.h" #include "core/PartitionActions.h" @@ -31,17 +30,22 @@ #include #include #include +#include class QBoxLayout; class QComboBox; class QLabel; class QListView; +namespace Calamares +{ +class PrettyRadioButton; +} + class PartitionBarsView; class PartitionSplitterWidget; class PartitionLabelsView; class PartitionCoreModule; -class PrettyRadioButton; class DeviceInfoWidget; class Device; @@ -153,10 +157,10 @@ private: QComboBox* m_drivesCombo; QButtonGroup* m_grp; - PrettyRadioButton* m_alongsideButton; - PrettyRadioButton* m_eraseButton; - PrettyRadioButton* m_replaceButton; - PrettyRadioButton* m_somethingElseButton; + Calamares::PrettyRadioButton* m_alongsideButton; + Calamares::PrettyRadioButton* m_eraseButton; + Calamares::PrettyRadioButton* m_replaceButton; + Calamares::PrettyRadioButton* m_somethingElseButton; QComboBox* m_eraseSwapChoiceComboBox; // UI, see also m_eraseSwapChoice DeviceInfoWidget* m_deviceInfoWidget; @@ -182,4 +186,4 @@ private: QMutex m_coreMutex; }; -#endif // CHOICEPAGE_H +#endif // CHOICEPAGE_H From 8465dcbc1902e4fea3af4ada38c02682c42b2af4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 19 May 2020 11:39:53 +0200 Subject: [PATCH 38/38] [calamares] Don't crash in test-loader - When loading *view* modules, we always need a QApplication for GUI bits, because the widget for a module is created is very early. - If it's a view module, replace the application object with one that supports GUIs; without the --ui flag, though, it will just run the jobs. --- src/calamares/testmain.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/calamares/testmain.cpp b/src/calamares/testmain.cpp index cd06c5d03..f353fa6d5 100644 --- a/src/calamares/testmain.cpp +++ b/src/calamares/testmain.cpp @@ -252,6 +252,12 @@ main( int argc, char* argv[] ) cDebug() << " .. got" << m->name() << m->typeString() << m->interfaceString(); if ( m->type() == Calamares::Module::Type::View ) { + if ( !qobject_cast< QApplication* >(aw) ) + { + auto* replace_app = new QApplication( argc, argv ); + replace_app->setQuitOnLastWindowClosed( true ); + aw = replace_app; + } mw = module.m_ui ? new QMainWindow() : nullptr; (void)new Calamares::Branding( module.m_branding );