diff --git a/src/modules/plasmalnf/CMakeLists.txt b/src/modules/plasmalnf/CMakeLists.txt index 9b3ccf716..61b44862f 100644 --- a/src/modules/plasmalnf/CMakeLists.txt +++ b/src/modules/plasmalnf/CMakeLists.txt @@ -1,6 +1,6 @@ find_package(ECM ${ECM_VERSION} REQUIRED NO_MODULE) -find_package( KF5 5.29 REQUIRED CoreAddons Plasma Service Package ) +find_package( KF5 5.29 REQUIRED CoreAddons Plasma Package ) calamares_add_plugin( plasmalnf TYPE viewmodule @@ -9,13 +9,11 @@ calamares_add_plugin( plasmalnf PlasmaLnfViewStep.cpp PlasmaLnfPage.cpp PlasmaLnfJob.cpp - PlasmaLnfInfo.cpp UI page_plasmalnf.ui LINK_PRIVATE_LIBRARIES calamaresui KF5::Package KF5::Plasma - KF5::Service SHARED_LIB ) diff --git a/src/modules/plasmalnf/PlasmaLnfInfo.cpp b/src/modules/plasmalnf/PlasmaLnfInfo.cpp deleted file mode 100644 index 6e9249825..000000000 --- a/src/modules/plasmalnf/PlasmaLnfInfo.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2017, 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 "PlasmaLnfInfo.h" - -#include -#include -#include -#include -#include - -#include -#include -#include // Future - -#include // TODO: port to KPluginLoader -#include -#include - -#include "utils/Logger.h" - - -namespace Calamares -{ - -QStringList themes_by_package() -{ - QStringList packages; - - QList pkgs = KPackage::PackageLoader::self()->listPackages("Plasma/LookAndFeel"); - - for (const KPluginMetaData &data : pkgs) { - packages << data.pluginId(); - } - - return packages; -} - - -QStringList themes_by_service() -{ - KService::List services; - KServiceTypeTrader* trader = KServiceTypeTrader::self(); - - cDebug() << "Plasma themes by service:"; - QStringList packages; - services = trader->query("Plasma/Theme"); - int c = 0; - for ( const auto s : services ) - { - cDebug() << " .. Plasma theme" << s->name(); - packages << s->name(); - c++; - } - - return packages; -} - -QStringList themes_by_kcm() -{ - QString component; - QList packages; - QStringList paths; - QStringList packageNames; - const QStringList dataPaths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); - - for (const QString &path : dataPaths) { - QDir dir(path + "/plasma/look-and-feel"); - paths << dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); - } - - cDebug() << "Plasma themes by kcm:"; - for (const QString &path : paths) { - Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel")); - pkg.setPath(path); - pkg.setFallbackPackage(Plasma::Package()); - if (component.isEmpty() || !pkg.filePath(component.toUtf8()).isEmpty()) { - packages << pkg; - packageNames << pkg.metadata().pluginName(); - cDebug() << " .. Plasma theme" << pkg.metadata().pluginName(); - } - } - - return packageNames; -} - -QStringList themes_by_lnftool() -{ - QStringList packages; - - QProcess lnftool; - lnftool.start( Calamares::lnftool(), {"--list"} ); - if ( lnftool.waitForStarted(1000) && lnftool.waitForFinished( 1000 ) && (lnftool.exitCode() == 0) && (lnftool.exitStatus() == QProcess::NormalExit ) ) - { - packages = QString::fromLocal8Bit( lnftool.readAllStandardOutput() ).trimmed().split('\n'); - } - return packages; -} - -QStringList plasma_themes() -{ - QStringList l( themes_by_package() ); - if (l.isEmpty()) - return themes_by_lnftool(); - return l; -} - -static QString *p_lnfPath = nullptr; - -QString lnftool() -{ - if ( !p_lnfPath ) - p_lnfPath = new QString("/usr/bin/lookandfeeltool"); - - return *p_lnfPath; -} - -void set_lnftool( const QString& lnfPath ) -{ - if (p_lnfPath) - delete p_lnfPath; - p_lnfPath = new QString( lnfPath ); -} - -} // namespace Calamares diff --git a/src/modules/plasmalnf/PlasmaLnfInfo.h b/src/modules/plasmalnf/PlasmaLnfInfo.h deleted file mode 100644 index 27adc224c..000000000 --- a/src/modules/plasmalnf/PlasmaLnfInfo.h +++ /dev/null @@ -1,39 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2017, 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 PLASMALNFINFO_H -#define PLASMALNFINFO_H - -#include -#include - -namespace Calamares -{ -QString lnftool(); -void set_lnftool( const QString& ); - - /* Internal */ -QStringList themes_by_package(); -QStringList themes_by_service(); -QStringList themes_by_kcm(); -QStringList themes_by_lnftool(); - -QStringList plasma_themes(); -} - -#endif // PLASMALNFINFO_H diff --git a/src/modules/plasmalnf/PlasmaLnfJob.cpp b/src/modules/plasmalnf/PlasmaLnfJob.cpp index e6a4fbe10..82d55f609 100644 --- a/src/modules/plasmalnf/PlasmaLnfJob.cpp +++ b/src/modules/plasmalnf/PlasmaLnfJob.cpp @@ -18,28 +18,14 @@ #include "PlasmaLnfJob.h" -#include -#include -#include -#include -#include - -#include -#include -#include // Future - -#include // TODO: port to KPluginLoader - -#include "CalamaresVersion.h" -#include "JobQueue.h" #include "GlobalStorage.h" - +#include "JobQueue.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" PlasmaLnfJob::PlasmaLnfJob( const QString& lnfPath, const QString& id ) : m_lnfPath( lnfPath ) - , m_id(id) + , m_id( id ) { } @@ -75,18 +61,17 @@ PlasmaLnfJob::exec() auto system = CalamaresUtils::System::instance(); Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - QStringList command; - - if ( !system->doChroot() ) - command << "sudo" << "-E" << "-H" << "-u" << gs->value("username").toString(); - - command << m_lnfPath << "-platform" << "minimal" << "--resetLayout" << "--apply" << m_id; + QStringList command( + { + "sudo", "-E", "-H", "-u", gs->value( "username" ).toString(), + m_lnfPath, "-platform", "minimal", "--resetLayout", "--apply", m_id + } ); int r = system->targetEnvCall( command ); - if (r) + if ( r ) return Calamares::JobResult::error( - tr( "Could not select KDE Plasma Look-and-Feel package" ), - tr( "Could not select KDE Plasma Look-and-Feel package" ) ); + tr( "Could not select KDE Plasma Look-and-Feel package" ), + tr( "Could not select KDE Plasma Look-and-Feel package" ) ); return Calamares::JobResult::ok(); } diff --git a/src/modules/plasmalnf/PlasmaLnfPage.cpp b/src/modules/plasmalnf/PlasmaLnfPage.cpp index 632b9f13a..01759ba32 100644 --- a/src/modules/plasmalnf/PlasmaLnfPage.cpp +++ b/src/modules/plasmalnf/PlasmaLnfPage.cpp @@ -17,54 +17,69 @@ */ #include "PlasmaLnfPage.h" -#include "PlasmaLnfInfo.h" #include "ui_page_plasmalnf.h" -#include "Branding.h" -#include "JobQueue.h" -#include "GlobalStorage.h" #include "utils/Logger.h" -#include "utils/CalamaresUtilsGui.h" #include "utils/Retranslator.h" -#include "ViewManager.h" -#include -#include -#include -#include +#include +#include -PlasmaLnfPage::PlasmaLnfPage(QWidget *parent) +static PlasmaLnfList plasma_themes() +{ + PlasmaLnfList packages; + + QList pkgs = KPackage::PackageLoader::self()->listPackages( "Plasma/LookAndFeel" ); + + for ( const KPluginMetaData& data : pkgs ) + { + packages << PlasmaLnfDescriptor{ data.pluginId(), data.name() }; + cDebug() << "LNF Package" << data.pluginId(); + cDebug() << " .." << data.name(); + cDebug() << " .." << data.description(); + cDebug() << " .." << 'V' << data.isValid() << 'H' << data.isHidden() << 'D' << data.isEnabledByDefault(); + } + + return packages; +} + + +PlasmaLnfPage::PlasmaLnfPage( QWidget* parent ) : QWidget( parent ) , ui( new Ui::PlasmaLnfPage ) { - using StringEntry = Calamares::Branding::StringEntry; - ui->setupUi( this ); CALAMARES_RETRANSLATE( + { ui->retranslateUi( this ); ui->generalExplanation->setText( tr( "Please choose a look-and-feel for the KDE Plasma Desktop, below." ) ); + m_availableLnf = plasma_themes(); + ui->lnfCombo->clear(); + for ( const auto& p : m_availableLnf ) + ui->lnfCombo->addItem( p.name ); + } ) - Calamares::themes_by_package(); - ui->lnfCombo->addItems( Calamares::plasma_themes() ); - - QObject::connect(ui->lnfCombo, &QComboBox::activated, this, &PlasmaLnfPage::activated); + QObject::connect( ui->lnfCombo, &QComboBox::activated, this, &PlasmaLnfPage::activated ); } void -PlasmaLnfPage::activated(const QString& name) +PlasmaLnfPage::activated( int index ) { - cDebug() << "Changed to" << name; - - QProcess lnftool; - lnftool.start( Calamares::lnftool(), {"--resetLayout", "--apply", name} ); - - if ( lnftool.waitForStarted(1000) && lnftool.waitForFinished( 1000 ) && (lnftool.exitCode() == 0) && (lnftool.exitStatus() == QProcess::NormalExit ) ) - ; // OK - else - cDebug() << "WARNING: could not apply look-and-feel" << name; + if ( ( index < 0 ) || ( index > m_availableLnf.length() ) ) + { + cDebug() << "Plasma LNF index" << index << "out of range."; + return; + } + const PlasmaLnfDescriptor& lnf = m_availableLnf.at( index ); + cDebug() << "Changed to" << index << lnf.id << lnf.name; + emit plasmaThemeSelected( lnf.id ); +} - emit plasmaThemeSelected( name ); +void +PlasmaLnfPage::setLnfPath( const QString& path ) +{ + m_lnfPath = path; } diff --git a/src/modules/plasmalnf/PlasmaLnfPage.h b/src/modules/plasmalnf/PlasmaLnfPage.h index ceed37044..31731eb0d 100644 --- a/src/modules/plasmalnf/PlasmaLnfPage.h +++ b/src/modules/plasmalnf/PlasmaLnfPage.h @@ -19,28 +19,41 @@ #ifndef PLASMALNFPAGE_H #define PLASMALNFPAGE_H +#include +#include #include -#include namespace Ui { class PlasmaLnfPage; } +struct PlasmaLnfDescriptor +{ + QString id; + QString name; +} ; + +using PlasmaLnfList = QList; + class PlasmaLnfPage : public QWidget { Q_OBJECT public: explicit PlasmaLnfPage( QWidget* parent = nullptr ); + void setLnfPath( const QString& path ); + public slots: - void activated(const QString& name); + void activated( int index ); signals: - void plasmaThemeSelected( const QString &id ); + void plasmaThemeSelected( const QString& id ); private: Ui::PlasmaLnfPage* ui; + QString m_lnfPath; + PlasmaLnfList m_availableLnf; }; #endif //PLASMALNFPAGE_H diff --git a/src/modules/plasmalnf/PlasmaLnfViewStep.cpp b/src/modules/plasmalnf/PlasmaLnfViewStep.cpp index 73f89091b..40c8a5c4a 100644 --- a/src/modules/plasmalnf/PlasmaLnfViewStep.cpp +++ b/src/modules/plasmalnf/PlasmaLnfViewStep.cpp @@ -15,19 +15,15 @@ * You should have received a copy of the GNU General Public License * along with Calamares. If not, see . */ +#include "PlasmaLnfViewStep.h" -#include "JobQueue.h" -#include "GlobalStorage.h" -#include "utils/Logger.h" -#include "utils/CalamaresUtils.h" -#include "utils/CalamaresUtilsSystem.h" - -#include "PlasmaLnfInfo.h" #include "PlasmaLnfJob.h" #include "PlasmaLnfPage.h" -#include "PlasmaLnfViewStep.h" -#include +#include "utils/CalamaresUtils.h" +#include "utils/Logger.h" + +#include #include CALAMARES_PLUGIN_FACTORY_DEFINITION( PlasmaLnfViewStepFactory, registerPlugin(); ) @@ -114,9 +110,7 @@ PlasmaLnfViewStep::jobs() const cDebug() << "Creating Plasma LNF jobs .."; if ( !m_themeId.isEmpty() && !m_lnfPath.isEmpty() ) - { l.append( Calamares::job_ptr( new PlasmaLnfJob( m_lnfPath, m_themeId ) ) ); - } return l; } @@ -125,14 +119,38 @@ void PlasmaLnfViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { m_lnfPath = CalamaresUtils::getString( configurationMap, "lnftool" ); - Calamares::set_lnftool( m_lnfPath ); + m_widget->setLnfPath( m_lnfPath ); - if (m_lnfPath.isEmpty()) + if ( m_lnfPath.isEmpty() ) cDebug() << "WARNING: no lnftool given for plasmalnf module."; + + m_liveUser = CalamaresUtils::getString( configurationMap, "liveuser" ); } void PlasmaLnfViewStep::themeSelected( const QString& id ) { m_themeId = id; + + QProcess lnftool; + if ( !m_liveUser.isEmpty() ) + lnftool.start( "sudo", {"-E", "-H", "-u", m_liveUser, m_lnfPath, "--resetLayout", "--apply", id} ); + else + lnftool.start( m_lnfPath, {"--resetLayout", "--apply", id} ); + + if ( !lnftool.waitForStarted( 1000 ) ) + { + cDebug() << "WARNING: could not start look-and-feel" << m_lnfPath; + return; + } + if ( !lnftool.waitForFinished() ) + { + cDebug() << "WARNING:" << m_lnfPath << "timed out."; + return; + } + + if ( ( lnftool.exitCode() == 0 ) && ( lnftool.exitStatus() == QProcess::NormalExit ) ) + cDebug() << "Plasma look-and-feel applied" << id; + else + cDebug() << "WARNING: could not apply look-and-feel" << id; } diff --git a/src/modules/plasmalnf/PlasmaLnfViewStep.h b/src/modules/plasmalnf/PlasmaLnfViewStep.h index c2bcce2c0..0ae74f7d5 100644 --- a/src/modules/plasmalnf/PlasmaLnfViewStep.h +++ b/src/modules/plasmalnf/PlasmaLnfViewStep.h @@ -57,12 +57,13 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; public slots: - void themeSelected( const QString &id ); + void themeSelected( const QString& id ); private: PlasmaLnfPage* m_widget; QString m_lnfPath; QString m_themeId; + QString m_liveUser; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( PlasmaLnfViewStepFactory ) diff --git a/src/modules/plasmalnf/plasmalnf.conf b/src/modules/plasmalnf/plasmalnf.conf index dec5c388c..1f0c72b25 100644 --- a/src/modules/plasmalnf/plasmalnf.conf +++ b/src/modules/plasmalnf/plasmalnf.conf @@ -12,3 +12,9 @@ # Full path to the Plasma look-and-feel tool (CLI program # for querying and applying Plasma themes). lnftool: "/usr/bin/lookandfeeltool" + +# For systems where the user Calamares runs as (usually root, +# via either sudo or pkexec) has a clean environment, set this +# to the originating username; the lnftool will be run through +# "sudo -H -u " instead of directly. +liveuser: "live" diff --git a/src/modules/welcome/checker/RequirementsChecker.cpp b/src/modules/welcome/checker/RequirementsChecker.cpp index 741802fb5..a815b6188 100644 --- a/src/modules/welcome/checker/RequirementsChecker.cpp +++ b/src/modules/welcome/checker/RequirementsChecker.cpp @@ -218,12 +218,16 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap ) bool ok = false; m_requiredStorageGB = configurationMap.value( "requiredStorage" ).toDouble( &ok ); if ( !ok ) + { + cDebug() << "WARNING: RequirementsChecker entry 'requiredStorage' is invalid."; m_requiredStorageGB = 3.; + } Calamares::JobQueue::instance()->globalStorage()->insert( "requiredStorageGB", m_requiredStorageGB ); } else { + cDebug() << "WARNING: RequirementsChecker entry 'requiredStorage' is missing."; m_requiredStorageGB = 3.; incompleteConfiguration = true; } @@ -236,12 +240,14 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap ) m_requiredRamGB = configurationMap.value( "requiredRam" ).toDouble( &ok ); if ( !ok ) { + cDebug() << "WARNING: RequirementsChecker entry 'requiredRam' is invalid."; m_requiredRamGB = 1.; incompleteConfiguration = true; } } else { + cDebug() << "WARNING: RequirementsChecker entry 'requiredRam' is missing."; m_requiredRamGB = 1.; incompleteConfiguration = true; } @@ -253,7 +259,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap ) if ( m_checkHasInternetUrl.isEmpty() || !QUrl( m_checkHasInternetUrl ).isValid() ) { - cDebug() << "Invalid internetCheckUrl in welcome.conf" << m_checkHasInternetUrl + cDebug() << "WARNING: RequirementsChecker entry 'internetCheckUrl' is invalid in welcome.conf" << m_checkHasInternetUrl << "reverting to default (http://example.com)."; m_checkHasInternetUrl = "http://example.com"; incompleteConfiguration = true; @@ -261,8 +267,9 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap ) } else { - cDebug() << "internetCheckUrl is undefined in welcome.conf, " + cDebug() << "WARNING: RequirementsChecker entry 'internetCheckUrl' is undefined in welcome.conf," "reverting to default (http://example.com)."; + m_checkHasInternetUrl = "http://example.com"; incompleteConfiguration = true; } @@ -274,7 +281,10 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap ) m_entriesToCheck.append( configurationMap.value( "check" ).toStringList() ); } else + { + cDebug() << "WARNING: RequirementsChecker entry 'check' is incomplete."; incompleteConfiguration = true; + } if ( configurationMap.contains( "required" ) && configurationMap.value( "required" ).type() == QVariant::List ) @@ -283,18 +293,13 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap ) m_entriesToRequire.append( configurationMap.value( "required" ).toStringList() ); } else + { + cDebug() << "WARNING: RequirementsChecker entry 'required' is incomplete."; incompleteConfiguration = true; + } if ( incompleteConfiguration ) - { - cDebug() << "WARNING: The RequirementsChecker configuration map provided by " - "the welcome module configuration file is incomplete or " - "incorrect.\n" - "Startup will continue for debugging purposes, but one or " - "more checks might not function correctly.\n" - "RequirementsChecker configuration map:\n" - << configurationMap; - } + cDebug() << "WARNING: RequirementsChecker configuration map:\n" << configurationMap; }