From adb312bdd271614251d03c709cd906ad8d4e1a3a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 14:19:33 +0100 Subject: [PATCH 01/78] [welcomeq] Coding style - a R/W property isn't CONSTANT - apply calamaresstyle --- src/modules/welcomeq/Config.cpp | 4 +--- src/modules/welcomeq/Config.h | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/modules/welcomeq/Config.cpp b/src/modules/welcomeq/Config.cpp index 6d085143c..e69f9f2dd 100644 --- a/src/modules/welcomeq/Config.cpp +++ b/src/modules/welcomeq/Config.cpp @@ -23,6 +23,4 @@ Config::Config() { } -Config::~Config() -{ -} +Config::~Config() {} diff --git a/src/modules/welcomeq/Config.h b/src/modules/welcomeq/Config.h index 2295d4ee2..59d90e31d 100644 --- a/src/modules/welcomeq/Config.h +++ b/src/modules/welcomeq/Config.h @@ -16,8 +16,8 @@ * along with Calamares. If not, see . */ -#ifndef WELCOME_CONFIG_H -#define WELCOME_CONFIG_H +#ifndef WELCOMEQ_CONFIG_H +#define WELCOMEQ_CONFIG_H #include #include @@ -25,7 +25,7 @@ class Config : public QObject { Q_OBJECT - Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl CONSTANT ) + Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl ) public: Config(); virtual ~Config(); From 7bf0fded1b7b917ca8e1555f7654d91f2dd89891 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 14:25:30 +0100 Subject: [PATCH 02/78] [welcomeq] Port to newer QmlViewStep --- src/modules/welcomeq/WelcomeQmlViewStep.cpp | 51 +-------------------- src/modules/welcomeq/WelcomeQmlViewStep.h | 29 ++---------- 2 files changed, 5 insertions(+), 75 deletions(-) diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.cpp b/src/modules/welcomeq/WelcomeQmlViewStep.cpp index 2a5b0f661..e43bddc54 100644 --- a/src/modules/welcomeq/WelcomeQmlViewStep.cpp +++ b/src/modules/welcomeq/WelcomeQmlViewStep.cpp @@ -37,7 +37,7 @@ CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeQmlViewStepFactory, registerPlugin< WelcomeQmlViewStep >(); ) WelcomeQmlViewStep::WelcomeQmlViewStep( QObject* parent ) - : Calamares::ViewStep( parent ) + : Calamares::QmlViewStep( QStringLiteral( "welcomeq" ), parent ) , m_requirementsChecker( new GeneralRequirements( this ) ) { connect( Calamares::ModuleManager::instance(), @@ -51,60 +51,12 @@ WelcomeQmlViewStep::~WelcomeQmlViewStep() { } - QString WelcomeQmlViewStep::prettyName() const { return tr( "Welcome" ); } - -QWidget* -WelcomeQmlViewStep::widget() -{ - return nullptr; -} - - -bool -WelcomeQmlViewStep::isNextEnabled() const -{ - // TODO: should return true - return false; -} - - -bool -WelcomeQmlViewStep::isBackEnabled() const -{ - // TODO: should return true (it's weird that you are not allowed to have welcome *after* anything - return false; -} - - -bool -WelcomeQmlViewStep::isAtBeginning() const -{ - // TODO: adjust to "pages" in the QML - return true; -} - - -bool -WelcomeQmlViewStep::isAtEnd() const -{ - // TODO: adjust to "pages" in the QML - return true; -} - - -Calamares::JobList -WelcomeQmlViewStep::jobs() const -{ - return Calamares::JobList(); -} - - /** @brief Look up a URL for a button * * Looks up @p key in @p map; if it is a *boolean* value, then @@ -140,6 +92,7 @@ jobOrBrandingSetting( Calamares::Branding::StringEntry e, const QVariantMap& map void WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { + QmlViewStep::setConfigurationMap( configurationMap ); using Calamares::Branding; m_config.setHelpUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) ); diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.h b/src/modules/welcomeq/WelcomeQmlViewStep.h index 5486d8d31..2bfe448a3 100644 --- a/src/modules/welcomeq/WelcomeQmlViewStep.h +++ b/src/modules/welcomeq/WelcomeQmlViewStep.h @@ -21,11 +21,10 @@ #include "Config.h" +#include "PluginDllMacro.h" #include "modulesystem/Requirement.h" #include "utils/PluginFactory.h" -#include "viewpages/ViewStep.h" - -#include +#include "viewpages/QmlViewStep.h" #include #include @@ -40,13 +39,7 @@ class Handler; class GeneralRequirements; -class QQmlComponent; -class QQuickItem; -class QQuickWidget; - -// TODO: Needs a generic Calamares::QmlViewStep as base class -// TODO: refactor and move what makes sense to base class -class PLUGINDLLEXPORT WelcomeQmlViewStep : public Calamares::ViewStep +class PLUGINDLLEXPORT WelcomeQmlViewStep : public Calamares::QmlViewStep { Q_OBJECT @@ -56,16 +49,6 @@ public: QString prettyName() const override; - QWidget* widget() override; - - bool isNextEnabled() const override; - bool isBackEnabled() const override; - - bool isAtBeginning() const override; - bool isAtEnd() const override; - - Calamares::JobList jobs() const override; - void setConfigurationMap( const QVariantMap& configurationMap ) override; /** @brief Sets the country that Calamares is running in. @@ -82,12 +65,6 @@ private: // TODO: a generic QML viewstep should return a config object from a method Config m_config; GeneralRequirements* m_requirementsChecker; - - // TODO: these need to be in the base class (also a base class of ExecutionViewStep) - QQuickWidget* m_qmlWidget; - QQmlComponent* m_qmlComponent; - QQuickItem* m_qmlItem; - }; CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeQmlViewStepFactory ) From b5e17b7ea5486dff912fa1f09bcc8da882f9058f Mon Sep 17 00:00:00 2001 From: Camilo Higuita Date: Sat, 14 Dec 2019 18:14:35 +0100 Subject: [PATCH 03/78] [welcomeq] Add full-featured QML for welcome page This is a merge of several commits by Camilo. --- src/modules/welcomeq/welcomeq.qml | 226 ++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 src/modules/welcomeq/welcomeq.qml diff --git a/src/modules/welcomeq/welcomeq.qml b/src/modules/welcomeq/welcomeq.qml new file mode 100644 index 000000000..051430e0e --- /dev/null +++ b/src/modules/welcomeq/welcomeq.qml @@ -0,0 +1,226 @@ +import io.calamares.modules 1.0 as Modules +import io.calamares.ui 1.0 + +import QtQuick 2.10 +import QtQuick.Controls 2.10 +import QtQuick.Layouts 1.3 +import org.kde.kirigami 2.7 as Kirigami +import org.kde.mauikit 1.0 as Maui +import QtGraphicalEffects 1.0 +import QtQuick.Window 2.3 + +ResponsiveBase +{ + id: control + + Modules.Welcome + { + id: _welcome + } + + nextButton.enabled: _welcome.Config.isNextEnabled + onNextClicked: + { + if (stackView.depth === 2) + return + + stackView.push(_langComponent) + } + + title: stackView.currentItem.title + subtitle: stackView.currentItem.subtitle + message: stackView.currentItem.message + + header: Item + { + width: parent.width + height: 150 + + Image + { + anchors.centerIn: parent + source: Branding.imagePath(Branding.ProductWelcome) + height: Math.min(100, parent.height) + width: height + sourceSize.width: width + sourceSize.height: height + } + } + + stackView.initialItem: Item + { + property string title: "Welcome to " + Branding.string(Branding.ProductName) + " " + Branding.string(Branding.Version) + property string subtitle: _welcome.Config.genericWelcomeMessage + property string message: _welcome.Config.warningMessage + + ListView + { + id: _requirementsList + anchors.centerIn: parent + implicitWidth: Math.min(parent.width, 500) + implicitHeight: Math.min(contentHeight, 500) + + Rectangle + { + z: parent.z - 1 + anchors.fill: parent + color: Kirigami.Theme.backgroundColor + radius: 5 + opacity: 0.5 + } + + model: _welcome.Config.requirementsModel + + delegate: ItemDelegate + { + id: _delegate + + background: Rectangle + { + color: model.satisfied ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.negativeTextColor + opacity: 0.2 + } + + width: parent.width + height: 48 + + contentItem: RowLayout + { + width: parent.width + height: parent.height + + Item + { + Layout.fillHeight: true + Layout.preferredWidth: height + + Kirigami.Icon + { + source: model.satisfied ? "checkmark" : (model.mandatory ? "error" : "dialog-warning-symbolic") + height: 32 + width: height + anchors.centerIn: parent + color: background.color + } + } + + ColumnLayout + { + Layout.fillWidth: true + Layout.fillHeight: true + + spacing: 0 + + Label + { + Layout.fillWidth: true + Layout.fillHeight: true + horizontalAlignment: Qt.AlignLeft + text: model.name + } + + Label + { + Layout.fillWidth: true + Layout.fillHeight: true + horizontalAlignment: Qt.AlignLeft + text: !model.satisfied ? model.negatedText : model.details + opacity: isCurrentItem ? 1 : 0.7 + font.weight: Font.Light + } + } + } + } + + footer: RowLayout + { + + width: parent.width + height: 64 + + spacing: Kirigami.Units.largeSpacing* 2 + + Button + { + Layout.fillWidth: true + text: "About" + icon.name: "documentinfo" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + + visible: Branding.string(Branding.ProductUrl).length + onClicked: Qt.openUrlExternally(Branding.string(Branding.ProductUrl)) + } + + Button + { + Layout.fillWidth: true + text: qsTr("Support") + icon.name: "help-contents" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + visible: Branding.string(Branding.SupportUrl).length + onClicked: Qt.openUrlExternally(Branding.string(Branding.SupportUrl)) + } + + Button + { + Layout.fillWidth: true + text: qsTr("Known issues") + icon.name: "tools-report-bug" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + visible: Branding.string(Branding.KnownIssuesUrl).length + onClicked: Qt.openUrlExternally(Branding.string(Branding.KnownIssuesUrl)) + } + + Button + { + Layout.fillWidth: true + text: qsTr("Release notes") + icon.name: "answer" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + visible: Branding.string(Branding.ReleaseNotesUrl).length + onClicked: Qt.openUrlExternally(Branding.string(Branding.ReleaseNotesUrl)) + } + + } + } + } + + + + + Component + { + id: _langComponent + + Item + { + property string title : qsTr("Language") + property string subtitle: qsTr("Select your preferred language to continue with the installation") + + ListViewTemplate + { + id: _langList + anchors.centerIn: parent + implicitWidth: Math.min(parent.width, 500) + implicitHeight: Math.min(contentHeight, 500) + + currentIndex: _welcome.Config.localeIndex + + model: _welcome.Config.languagesModel + + delegate: ListItemDelegate + { + id: _delegate + label1.text: model.label + label2.text: model.englishLabel + } + } + } + + } + +} From 152c3352c2b42cd28329a3c32189ea4850a26c65 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 15:08:18 +0100 Subject: [PATCH 04/78] [welcomeq] Compile the QML into the module - Default implementation is in the QRC - Register Branding for QML modules (just once) --- src/libcalamaresui/viewpages/QmlViewStep.cpp | 17 ++ src/modules/welcomeq/welcomeq.qml | 203 +------------------ src/modules/welcomeq/welcomeq.qrc | 5 + 3 files changed, 25 insertions(+), 200 deletions(-) create mode 100644 src/modules/welcomeq/welcomeq.qrc diff --git a/src/libcalamaresui/viewpages/QmlViewStep.cpp b/src/libcalamaresui/viewpages/QmlViewStep.cpp index 2bfc72757..582389a5e 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.cpp +++ b/src/libcalamaresui/viewpages/QmlViewStep.cpp @@ -35,6 +35,7 @@ #include #include + static const NamedEnumTable< Calamares::QmlViewStep::QmlSearch >& searchNames() { @@ -82,6 +83,20 @@ changeQMLState( QMLAction action, QQuickItem* item ) } } +static void +registerCalamaresModels() +{ + static bool done = false; + if ( !done ) + { + done = true; + qmlRegisterSingletonType< Calamares::Branding >( + "calamares.ui", 1, 0, "Branding", []( QQmlEngine*, QJSEngine* ) -> QObject* { + return Calamares::Branding::instance(); + } ); + } +} + namespace Calamares { @@ -92,6 +107,8 @@ QmlViewStep::QmlViewStep( const QString& name, QObject* parent ) , m_spinner( new WaitingWidget( tr( "Loading ..." ) ) ) , m_qmlWidget( new QQuickWidget ) { + registerCalamaresModels(); + QVBoxLayout* layout = new QVBoxLayout( m_widget ); layout->addWidget( m_spinner ); diff --git a/src/modules/welcomeq/welcomeq.qml b/src/modules/welcomeq/welcomeq.qml index 051430e0e..604a90f66 100644 --- a/src/modules/welcomeq/welcomeq.qml +++ b/src/modules/welcomeq/welcomeq.qml @@ -1,35 +1,15 @@ -import io.calamares.modules 1.0 as Modules -import io.calamares.ui 1.0 +import calamares.ui 1.0 import QtQuick 2.10 import QtQuick.Controls 2.10 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami -import org.kde.mauikit 1.0 as Maui import QtGraphicalEffects 1.0 import QtQuick.Window 2.3 -ResponsiveBase +Page { - id: control - - Modules.Welcome - { - id: _welcome - } - - nextButton.enabled: _welcome.Config.isNextEnabled - onNextClicked: - { - if (stackView.depth === 2) - return - - stackView.push(_langComponent) - } - - title: stackView.currentItem.title - subtitle: stackView.currentItem.subtitle - message: stackView.currentItem.message + id: welcome header: Item { @@ -46,181 +26,4 @@ ResponsiveBase sourceSize.height: height } } - - stackView.initialItem: Item - { - property string title: "Welcome to " + Branding.string(Branding.ProductName) + " " + Branding.string(Branding.Version) - property string subtitle: _welcome.Config.genericWelcomeMessage - property string message: _welcome.Config.warningMessage - - ListView - { - id: _requirementsList - anchors.centerIn: parent - implicitWidth: Math.min(parent.width, 500) - implicitHeight: Math.min(contentHeight, 500) - - Rectangle - { - z: parent.z - 1 - anchors.fill: parent - color: Kirigami.Theme.backgroundColor - radius: 5 - opacity: 0.5 - } - - model: _welcome.Config.requirementsModel - - delegate: ItemDelegate - { - id: _delegate - - background: Rectangle - { - color: model.satisfied ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.negativeTextColor - opacity: 0.2 - } - - width: parent.width - height: 48 - - contentItem: RowLayout - { - width: parent.width - height: parent.height - - Item - { - Layout.fillHeight: true - Layout.preferredWidth: height - - Kirigami.Icon - { - source: model.satisfied ? "checkmark" : (model.mandatory ? "error" : "dialog-warning-symbolic") - height: 32 - width: height - anchors.centerIn: parent - color: background.color - } - } - - ColumnLayout - { - Layout.fillWidth: true - Layout.fillHeight: true - - spacing: 0 - - Label - { - Layout.fillWidth: true - Layout.fillHeight: true - horizontalAlignment: Qt.AlignLeft - text: model.name - } - - Label - { - Layout.fillWidth: true - Layout.fillHeight: true - horizontalAlignment: Qt.AlignLeft - text: !model.satisfied ? model.negatedText : model.details - opacity: isCurrentItem ? 1 : 0.7 - font.weight: Font.Light - } - } - } - } - - footer: RowLayout - { - - width: parent.width - height: 64 - - spacing: Kirigami.Units.largeSpacing* 2 - - Button - { - Layout.fillWidth: true - text: "About" - icon.name: "documentinfo" - Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) - Kirigami.Theme.textColor: "#fff" - - visible: Branding.string(Branding.ProductUrl).length - onClicked: Qt.openUrlExternally(Branding.string(Branding.ProductUrl)) - } - - Button - { - Layout.fillWidth: true - text: qsTr("Support") - icon.name: "help-contents" - Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) - Kirigami.Theme.textColor: "#fff" - visible: Branding.string(Branding.SupportUrl).length - onClicked: Qt.openUrlExternally(Branding.string(Branding.SupportUrl)) - } - - Button - { - Layout.fillWidth: true - text: qsTr("Known issues") - icon.name: "tools-report-bug" - Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) - Kirigami.Theme.textColor: "#fff" - visible: Branding.string(Branding.KnownIssuesUrl).length - onClicked: Qt.openUrlExternally(Branding.string(Branding.KnownIssuesUrl)) - } - - Button - { - Layout.fillWidth: true - text: qsTr("Release notes") - icon.name: "answer" - Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) - Kirigami.Theme.textColor: "#fff" - visible: Branding.string(Branding.ReleaseNotesUrl).length - onClicked: Qt.openUrlExternally(Branding.string(Branding.ReleaseNotesUrl)) - } - - } - } - } - - - - - Component - { - id: _langComponent - - Item - { - property string title : qsTr("Language") - property string subtitle: qsTr("Select your preferred language to continue with the installation") - - ListViewTemplate - { - id: _langList - anchors.centerIn: parent - implicitWidth: Math.min(parent.width, 500) - implicitHeight: Math.min(contentHeight, 500) - - currentIndex: _welcome.Config.localeIndex - - model: _welcome.Config.languagesModel - - delegate: ListItemDelegate - { - id: _delegate - label1.text: model.label - label2.text: model.englishLabel - } - } - } - - } - } diff --git a/src/modules/welcomeq/welcomeq.qrc b/src/modules/welcomeq/welcomeq.qrc new file mode 100644 index 000000000..772bf7e88 --- /dev/null +++ b/src/modules/welcomeq/welcomeq.qrc @@ -0,0 +1,5 @@ + + + welcomeq.qml + + From 15d850372646586f5a935d1978c67c707d8b4e85 Mon Sep 17 00:00:00 2001 From: Camilo Higuita Date: Fri, 13 Dec 2019 22:09:27 +0100 Subject: [PATCH 05/78] [libcalamaresui] Expose the branding strings & urls to qml --- src/libcalamaresui/Branding.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index e3952881e..619847d71 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -146,9 +146,6 @@ public: QString slideshowPath() const { return m_slideshowPath; } int slideshowAPI() const { return m_slideshowAPI; } - QString string( Branding::StringEntry stringEntry ) const; - QString styleString( Branding::StyleEntry styleEntry ) const; - QString imagePath( Branding::ImageEntry imageEntry ) const; QPixmap image( Branding::ImageEntry imageEntry, const QSize& size ) const; /** @brief Look up an image in the branding directory or as an icon @@ -185,6 +182,11 @@ public: */ void setGlobals( GlobalStorage* globalStorage ) const; +public slots: + QString string( Branding::StringEntry stringEntry ) const; + QString styleString( Branding::StyleEntry styleEntry ) const; + QString imagePath( Branding::ImageEntry imageEntry ) const; + private: static Branding* s_instance; From 18942f835f200d6e6b6e9c969c37104bafa73ada Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 15:35:11 +0100 Subject: [PATCH 06/78] [libcalamares] Remove confusing name-qualifiers - Using Branding::ImageEntry, when ImageEntry is an enum class defined *in* Branding, is superfluous, and it also confuses moc; the enum type isn't recognized from QML. --- src/libcalamaresui/Branding.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 619847d71..0912ff89f 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -183,9 +183,9 @@ public: void setGlobals( GlobalStorage* globalStorage ) const; public slots: - QString string( Branding::StringEntry stringEntry ) const; - QString styleString( Branding::StyleEntry styleEntry ) const; - QString imagePath( Branding::ImageEntry imageEntry ) const; + QString string( StringEntry stringEntry ) const; + QString styleString( StyleEntry styleEntry ) const; + QString imagePath( ImageEntry imageEntry ) const; private: static Branding* s_instance; From ae35256177a6b6a2680ece86d77743cccd79784d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 16:03:19 +0100 Subject: [PATCH 07/78] [welcomeq] Add top-text - Fix QML indentation to the canonical 4-spaces - Add a header at the top of the page - Force the image to load from the filesystem --- src/modules/welcomeq/welcomeq.qml | 59 +++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/modules/welcomeq/welcomeq.qml b/src/modules/welcomeq/welcomeq.qml index 604a90f66..d6ce9342b 100644 --- a/src/modules/welcomeq/welcomeq.qml +++ b/src/modules/welcomeq/welcomeq.qml @@ -1,3 +1,20 @@ +/* === This file is part of Calamares - === + * + * 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 + * 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 . + */ import calamares.ui 1.0 import QtQuick 2.10 @@ -9,21 +26,33 @@ import QtQuick.Window 2.3 Page { - id: welcome + id: welcome - header: Item - { - width: parent.width - height: 150 + header: Item + { + width: parent.width + height: 150 - Image - { - anchors.centerIn: parent - source: Branding.imagePath(Branding.ProductWelcome) - height: Math.min(100, parent.height) - width: height - sourceSize.width: width - sourceSize.height: height - } - } + Text + { + id: welcomeTopText + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + // In QML, QString::arg() only takes one argument + text: qsTr("

%1 %2

").arg(Branding.string(Branding.ProductName)).arg(Branding.string(Branding.Version)) + } + Image + { + id: welcomeImage + anchors.centerIn: parent + // imagePath() returns a full pathname, so make it refer to the filesystem + // .. otherwise the path is interpreted relative to the "call site", which + // .. might be the QRC file. + source: "file:/" + Branding.imagePath(Branding.ProductWelcome) + height: Math.min(100, parent.height) + width: height + sourceSize.width: width + sourceSize.height: height + } + } } From 86bf9287ab1341820db08606fc910476a9f577ae Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 16:21:13 +0100 Subject: [PATCH 08/78] [notesqml] Use Branding strings --- src/modules/notesqml/notesqml.qml | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/modules/notesqml/notesqml.qml b/src/modules/notesqml/notesqml.qml index d1ff4f1b5..a41fa98fd 100644 --- a/src/modules/notesqml/notesqml.qml +++ b/src/modules/notesqml/notesqml.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,14 @@ * along with Calamares. If not, see . */ +/* Some Calamares internals are available to all QML modules. + * They live in the calamares.ui namespace (filled programmatically + * by Calamares). One of the internals that is exposed is the + * Branding object, which can be used to retrieve strings and paths + * and colors. + */ +import calamares.ui 1.0 + import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Window 2.2 @@ -30,9 +39,9 @@ Item { id: flick anchors.fill: parent contentHeight: 800 - + ScrollBar.vertical: ScrollBar { - id: fscrollbar + id: fscrollbar width: 10 policy: ScrollBar.AlwaysOn } @@ -48,27 +57,27 @@ Item { activeFocusOnPress: false wrapMode: Text.WordWrap - text: qsTr("

Generic GNU/Linux 2020.2 LTS Turgid Tuba

+ text: qsTr("

%1

This an example QML file, showing options in RichText with Flickable content.

- +

QML with RichText can use HTML tags, Flickable content is useful for touchscreens.

- +

This is bold text

This is italic text

This is underlined text

This text will be center-aligned.

This is strikethrough

- +

Code example: ls -l /home

- +

Lists:

  • Intel CPU systems
  • AMD CPU systems
- -

The vertical scrollbar is adjustable, current width set to 10.

") + +

The vertical scrollbar is adjustable, current width set to 10.

").arg(Branding.string(Branding.VersionedName)) } } From f0134aab71b507ac200b41ebd5b72dcc27bbebd4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 17:31:32 +0100 Subject: [PATCH 09/78] [welcomeq] Add more fields to Config - getters as slots, for later access from QML --- src/modules/welcomeq/Config.cpp | 5 +---- src/modules/welcomeq/Config.h | 17 ++++++++++++++--- src/modules/welcomeq/WelcomeQmlViewStep.cpp | 8 ++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/modules/welcomeq/Config.cpp b/src/modules/welcomeq/Config.cpp index e69f9f2dd..cfa6336e2 100644 --- a/src/modules/welcomeq/Config.cpp +++ b/src/modules/welcomeq/Config.cpp @@ -18,9 +18,6 @@ #include "Config.h" -Config::Config() - : m_helpUrl( "https://www.kde.org/" ) -{ -} +Config::Config() {} Config::~Config() {} diff --git a/src/modules/welcomeq/Config.h b/src/modules/welcomeq/Config.h index 59d90e31d..01c841068 100644 --- a/src/modules/welcomeq/Config.h +++ b/src/modules/welcomeq/Config.h @@ -25,16 +25,27 @@ class Config : public QObject { Q_OBJECT - Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl ) + Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl FINAL ) + Q_PROPERTY( QUrl issuesUrl READ issuesUrl WRITE setIssuesUrl FINAL ) + Q_PROPERTY( QUrl notesUrl READ notesUrl WRITE setNotesUrl FINAL ) + Q_PROPERTY( QUrl donateUrl READ donateUrl WRITE setDonateUrl FINAL ) public: Config(); virtual ~Config(); - QUrl helpUrl() const { return m_helpUrl; } void setHelpUrl( const QUrl& url ) { m_helpUrl = url; } + void setIssuesUrl( const QUrl& url ) { m_issuesUrl = url; } + void setNotesUrl( const QUrl& url ) { m_notesUrl = url; } + void setDonateUrl( const QUrl& url ) { m_donateUrl = url; } + +public slots: + QUrl helpUrl() const { return m_helpUrl; } + QUrl issuesUrl() const { return m_issuesUrl; } + QUrl notesUrl() const { return m_notesUrl; } + QUrl donateUrl() const { return m_donateUrl; } private: - QUrl m_helpUrl; + QUrl m_helpUrl, m_issuesUrl, m_notesUrl, m_donateUrl; }; #endif diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.cpp b/src/modules/welcomeq/WelcomeQmlViewStep.cpp index e43bddc54..fbed4c382 100644 --- a/src/modules/welcomeq/WelcomeQmlViewStep.cpp +++ b/src/modules/welcomeq/WelcomeQmlViewStep.cpp @@ -47,9 +47,7 @@ WelcomeQmlViewStep::WelcomeQmlViewStep( QObject* parent ) } -WelcomeQmlViewStep::~WelcomeQmlViewStep() -{ -} +WelcomeQmlViewStep::~WelcomeQmlViewStep() {} QString WelcomeQmlViewStep::prettyName() const @@ -96,7 +94,9 @@ WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap ) using Calamares::Branding; m_config.setHelpUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) ); - // TODO: expand Config class and set the remaining fields + m_config.setIssuesUrl( jobOrBrandingSetting( Branding::KnownIssuesUrl, configurationMap, "showKnownIssuesUrl" ) ); + m_config.setNotesUrl( jobOrBrandingSetting( Branding::ReleaseNotesUrl, configurationMap, "showReleaseNotesUrl" ) ); + m_config.setDonateUrl( CalamaresUtils::getString( configurationMap, "showDonateUrl" ) ); // TODO: figure out how the requirements (held by ModuleManager) should be accessible // to QML as a odel. From 49ed97cb7792053b45dc5721c20766df77ab56f3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 17:51:10 +0100 Subject: [PATCH 10/78] [libcalamares] Allow QML ViewSteps to expose a config object --- src/libcalamaresui/viewpages/QmlViewStep.cpp | 12 ++++++++++++ src/libcalamaresui/viewpages/QmlViewStep.h | 12 ++++++++++++ src/modules/welcomeq/WelcomeQmlViewStep.cpp | 6 ++++++ src/modules/welcomeq/WelcomeQmlViewStep.h | 3 +++ 4 files changed, 33 insertions(+) diff --git a/src/libcalamaresui/viewpages/QmlViewStep.cpp b/src/libcalamaresui/viewpages/QmlViewStep.cpp index 582389a5e..7a38fb588 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.cpp +++ b/src/libcalamaresui/viewpages/QmlViewStep.cpp @@ -29,6 +29,7 @@ #include "widgets/WaitingWidget.h" #include +#include #include #include #include @@ -209,6 +210,11 @@ QmlViewStep::loadComplete() // 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. + QObject* config = this->getConfig(); + if ( config ) + { + m_qmlWidget->engine()->rootContext()->setContextProperty( "config", config ); + } m_qmlWidget->setContent( QUrl( m_qmlFileName ), m_qmlComponent, m_qmlObject ); showQml(); } @@ -336,4 +342,10 @@ QmlViewStep::showFailedQml() m_spinner->setText( prettyName() + ' ' + tr( "Loading failed." ) ); } +QObject* +QmlViewStep::getConfig() +{ + return nullptr; +} + } // namespace Calamares diff --git a/src/libcalamaresui/viewpages/QmlViewStep.h b/src/libcalamaresui/viewpages/QmlViewStep.h index 46ba29a53..038569927 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.h +++ b/src/libcalamaresui/viewpages/QmlViewStep.h @@ -76,6 +76,18 @@ public: /// @brief Configure search paths; subclasses should call this as well virtual void setConfigurationMap( const QVariantMap& configurationMap ) override; +protected: + /** @brief Gets a pointer to the Config of this view step + * + * Parts of the configuration of the viewstep can be passed to QML + * by placing them in a QObject (as properties). The default + * implementation returns nullptr, for no-config. + * + * Ownership of the config object remains with the ViewStep; it is possible + * to return a pointer to a member variable. + */ + virtual QObject* getConfig(); + private Q_SLOTS: void loadComplete(); diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.cpp b/src/modules/welcomeq/WelcomeQmlViewStep.cpp index fbed4c382..580b183d1 100644 --- a/src/modules/welcomeq/WelcomeQmlViewStep.cpp +++ b/src/modules/welcomeq/WelcomeQmlViewStep.cpp @@ -194,3 +194,9 @@ WelcomeQmlViewStep::setCountry( const QString& countryCode, CalamaresUtils::GeoI } } } + +QObject* +WelcomeQmlViewStep::getConfig() +{ + return &m_config; +} diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.h b/src/modules/welcomeq/WelcomeQmlViewStep.h index 2bfe448a3..a497f4c40 100644 --- a/src/modules/welcomeq/WelcomeQmlViewStep.h +++ b/src/modules/welcomeq/WelcomeQmlViewStep.h @@ -61,6 +61,9 @@ public: Calamares::RequirementsList checkRequirements() override; +protected: + QObject* getConfig() override; + private: // TODO: a generic QML viewstep should return a config object from a method Config m_config; From 85b873a1a286230c7dd5f03a0ce3345505ec3735 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 17:58:21 +0100 Subject: [PATCH 11/78] [libcalamaresui] Log QML error message - When loading fails, log a useful error message from the QML engine (to help debug the QML) --- src/libcalamaresui/viewpages/QmlViewStep.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libcalamaresui/viewpages/QmlViewStep.cpp b/src/libcalamaresui/viewpages/QmlViewStep.cpp index 7a38fb588..4ae640eee 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.cpp +++ b/src/libcalamaresui/viewpages/QmlViewStep.cpp @@ -339,6 +339,10 @@ void QmlViewStep::showFailedQml() { cWarning() << "QmlViewStep" << moduleInstanceKey() << "loading failed."; + if ( m_qmlComponent ) + { + cDebug() << Logger::SubEntry << "QML error:" << m_qmlComponent->errorString(); + } m_spinner->setText( prettyName() + ' ' + tr( "Loading failed." ) ); } From 7e0cc7af419b1934e88ddaab2beaa17e4a97722f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 18:24:07 +0100 Subject: [PATCH 12/78] [welcomeq] Add configuration file - copy the buttons-config part from welcome.conf - create buttons in the QML part --- src/modules/welcomeq/welcomeq.conf | 25 +++++++++++ src/modules/welcomeq/welcomeq.qml | 71 ++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/modules/welcomeq/welcomeq.conf diff --git a/src/modules/welcomeq/welcomeq.conf b/src/modules/welcomeq/welcomeq.conf new file mode 100644 index 000000000..0068ebe5c --- /dev/null +++ b/src/modules/welcomeq/welcomeq.conf @@ -0,0 +1,25 @@ +# Configuration for the welcome module. The welcome page +# displays some information from the branding file. +# Which parts it displays can be configured through +# the show* variables. +# +# In addition to displaying the welcome page, this module +# can check requirements for installation. +--- +# Display settings for various buttons on the welcome page. +# The URLs themselves come from branding.desc is the setting +# here is "true". If the setting is false, the button is hidden. +# The setting can also be a full URL which will then be used +# instead of the one from the branding file, or empty or not-set +# which will hide the button. +showSupportUrl: true +showKnownIssuesUrl: true +showReleaseNotesUrl: true + +# If this Url is set to something non-empty, a "donate" +# button is added to the welcome page alongside the +# others (see settings, above). Clicking the button opens +# the corresponding link. (This button has no corresponding +# branding.desc string) +# +# showDonateUrl: https://kde.org/community/donations/ diff --git a/src/modules/welcomeq/welcomeq.qml b/src/modules/welcomeq/welcomeq.qml index d6ce9342b..b40ec4813 100644 --- a/src/modules/welcomeq/welcomeq.qml +++ b/src/modules/welcomeq/welcomeq.qml @@ -54,5 +54,76 @@ Page sourceSize.width: width sourceSize.height: height } + + RowLayout + { + id: buttonBar + width: parent.width + height: 64 + + anchors.bottom: parent.bottom + + spacing: Kirigami.Units.largeSpacing* 2 + +/* Traditionally Calamares has had an "About" button that talks about + * Calamares itself, which just isn't a very useful thing in someone + * else's installation ISO. + */ + Button + { + Layout.fillWidth: true + text: qsTr("About") + icon.name: "documentinfo" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + + visible: false + onClicked: { } // TODO: show an about-Calamares window + } + Button + { + Layout.fillWidth: true + text: qsTr("Support") + icon.name: "documentinfo" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + + visible: config.helpUrl.isValid + onClicked: Qt.openUrlExternally(config.helpUrl) + } + Button + { + Layout.fillWidth: true + text: qsTr("Known issues") + icon.name: "documentinfo" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + + visible: config.issuesUrl.isValid + onClicked: Qt.openUrlExternally(config.issuesUrl) + } + Button + { + Layout.fillWidth: true + text: qsTr("Release notes") + icon.name: "documentinfo" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + + visible: config.notesUrl.isValid + onClicked: Qt.openUrlExternally(config.notesUrl) + } + Button + { + Layout.fillWidth: true + text: qsTr("Donate") + icon.name: "documentinfo" + Kirigami.Theme.backgroundColor: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.4) + Kirigami.Theme.textColor: "#fff" + + visible: config.donateUrl.isValid + onClicked: Qt.openUrlExternally(config.donateUrl) + } + } } } From f094cb543bf9b430cb6ffff75f5c8f9acbae2988 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 22:33:49 +0100 Subject: [PATCH 13/78] [libcalamaresui] Set config object earlier - The config context object should be set earlier, otherwise QML code will try binding to a non-existent config already - Document that QMLViewStep::setConfigurationMap() parent implementation should be called **last**, at the end of the subclass implementation. --- src/libcalamaresui/viewpages/QmlViewStep.cpp | 11 ++++++----- src/libcalamaresui/viewpages/QmlViewStep.h | 2 +- src/modules/notesqml/NotesQmlViewStep.cpp | 7 +++---- src/modules/welcomeq/WelcomeQmlViewStep.cpp | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libcalamaresui/viewpages/QmlViewStep.cpp b/src/libcalamaresui/viewpages/QmlViewStep.cpp index 4ae640eee..e13e022d8 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.cpp +++ b/src/libcalamaresui/viewpages/QmlViewStep.cpp @@ -210,11 +210,6 @@ QmlViewStep::loadComplete() // 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. - QObject* config = this->getConfig(); - if ( config ) - { - m_qmlWidget->engine()->rootContext()->setContextProperty( "config", config ); - } m_qmlWidget->setContent( QUrl( m_qmlFileName ), m_qmlComponent, m_qmlObject ); showQml(); } @@ -320,6 +315,12 @@ QmlViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { m_qmlFileName = searchQmlFile( m_searchMethod, qmlFile, m_name ); + QObject* config = this->getConfig(); + if ( config ) + { + m_qmlWidget->engine()->rootContext()->setContextProperty( "config", config ); + } + cDebug() << "QmlViewStep" << moduleInstanceKey() << "loading" << m_qmlFileName; m_qmlComponent = new QQmlComponent( m_qmlWidget->engine(), QUrl( m_qmlFileName ), QQmlComponent::CompilationMode::Asynchronous ); diff --git a/src/libcalamaresui/viewpages/QmlViewStep.h b/src/libcalamaresui/viewpages/QmlViewStep.h index 038569927..b54dc2fb7 100644 --- a/src/libcalamaresui/viewpages/QmlViewStep.h +++ b/src/libcalamaresui/viewpages/QmlViewStep.h @@ -73,7 +73,7 @@ public: /// @brief QML widgets don't produce jobs by default virtual JobList jobs() const override; - /// @brief Configure search paths; subclasses should call this as well + /// @brief Configure search paths; subclasses should call this at the **end** of their own implementation virtual void setConfigurationMap( const QVariantMap& configurationMap ) override; protected: diff --git a/src/modules/notesqml/NotesQmlViewStep.cpp b/src/modules/notesqml/NotesQmlViewStep.cpp index e729c2df7..79c2e39f2 100644 --- a/src/modules/notesqml/NotesQmlViewStep.cpp +++ b/src/modules/notesqml/NotesQmlViewStep.cpp @@ -36,9 +36,7 @@ NotesQmlViewStep::prettyName() const void NotesQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap ) -{ - Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation - +{ bool qmlLabel_ok = false; auto qmlLabel = CalamaresUtils::getSubMap( configurationMap, "qmlLabel", qmlLabel_ok ); @@ -46,7 +44,8 @@ NotesQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { m_notesName = new CalamaresUtils::Locale::TranslatedString( qmlLabel, "notes" ); } - + + Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last } CALAMARES_PLUGIN_FACTORY_DEFINITION( NotesQmlViewStepFactory, registerPlugin< NotesQmlViewStep >(); ) diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.cpp b/src/modules/welcomeq/WelcomeQmlViewStep.cpp index 580b183d1..382e0b4d1 100644 --- a/src/modules/welcomeq/WelcomeQmlViewStep.cpp +++ b/src/modules/welcomeq/WelcomeQmlViewStep.cpp @@ -90,7 +90,6 @@ jobOrBrandingSetting( Calamares::Branding::StringEntry e, const QVariantMap& map void WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { - QmlViewStep::setConfigurationMap( configurationMap ); using Calamares::Branding; m_config.setHelpUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) ); @@ -146,6 +145,8 @@ WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap ) // TODO: figure out where to set this: Config? } } + + QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last } Calamares::RequirementsList From aa0a7994928940b24de2b5ee8b99325af4eaf5c8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Feb 2020 22:47:11 +0100 Subject: [PATCH 14/78] [welcomeq] QML warnings-- The config bits are all constant, so avoid NOTIFY warnings. --- src/modules/welcomeq/Config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/welcomeq/Config.h b/src/modules/welcomeq/Config.h index 01c841068..50c3e387b 100644 --- a/src/modules/welcomeq/Config.h +++ b/src/modules/welcomeq/Config.h @@ -25,10 +25,10 @@ class Config : public QObject { Q_OBJECT - Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl FINAL ) - Q_PROPERTY( QUrl issuesUrl READ issuesUrl WRITE setIssuesUrl FINAL ) - Q_PROPERTY( QUrl notesUrl READ notesUrl WRITE setNotesUrl FINAL ) - Q_PROPERTY( QUrl donateUrl READ donateUrl WRITE setDonateUrl FINAL ) + Q_PROPERTY( QUrl helpUrl READ helpUrl CONSTANT FINAL ) + Q_PROPERTY( QUrl issuesUrl READ issuesUrl CONSTANT FINAL ) + Q_PROPERTY( QUrl notesUrl READ notesUrl CONSTANT FINAL ) + Q_PROPERTY( QUrl donateUrl READ donateUrl CONSTANT FINAL ) public: Config(); virtual ~Config(); From 7c323bdcdc1f87ac831b26f64be0b0b56adfe87a Mon Sep 17 00:00:00 2001 From: Gabriel Craciunescu Date: Thu, 2 Nov 2017 16:35:53 +0100 Subject: [PATCH 15/78] [users] Try to guess suggested hostname from dmi - nothing compicated for now, just try to get something from /sys/devices/virtual/dmi/id/product_name and fallback to -pc thingy if we can't --- src/modules/users/UsersPage.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index a7c72ce69..a757f5d5a 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -3,6 +3,7 @@ * Copyright 2014-2017, Teo Mrnjavac * Copyright 2017-2018, Adriaan de Groot * Copyright 2019, Collabora Ltd + * Copyright 2020, Gabriel Craciunescu * * Portions from the Manjaro Installation Framework * by Roland Singer @@ -40,6 +41,7 @@ #include "utils/String.h" #include +#include #include #include #include @@ -303,7 +305,27 @@ UsersPage::fillSuggestions() { if ( !cleanParts.isEmpty() && !cleanParts.first().isEmpty() ) { - QString hostnameSuggestion = QString( "%1-pc" ).arg( cleanParts.first() ); + + QString dmiProductName; + QString hostnameSuggestion; + // yes validateHostnameText() but these files can be a mess + QRegExp dmirx( "[^a-zA-Z0-9]", Qt::CaseInsensitive ); + QFile dmiFile( QStringLiteral( "/sys/devices/virtual/dmi/id/product_name" ) ); + + if ( dmiFile.exists() && + dmiFile.open(QIODevice::ReadOnly)) + { + dmiProductName = QString::fromLocal8Bit( dmiFile.readAll().simplified().data() ) + .toLower().replace(dmirx, " ").remove(' '); + } + if ( !dmiProductName.isEmpty() ) + { + hostnameSuggestion = QString( "%1-%2" ).arg( cleanParts.first() ).arg( dmiProductName ); + } + else + { + hostnameSuggestion = QString( "%1-pc" ).arg( cleanParts.first() ); + } if ( HOSTNAME_RX.indexIn( hostnameSuggestion ) != -1 ) { ui->textBoxHostname->setText( hostnameSuggestion ); From 2bb4dd8e22bdee360803ef10f42873da47242b7d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 11:45:45 +0100 Subject: [PATCH 16/78] [users] Refactor hostname-guessing --- src/modules/users/UsersPage.cpp | 54 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index a757f5d5a..ac6ff974c 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -271,6 +271,38 @@ UsersPage::onFullNameTextEdited( const QString& textRef ) checkReady( isReady() ); } +/** @brief Guess the machine's name + * + * If there is DMI data, use that; otherwise, just call the machine "-pc". + * Reads the DMI data just once. + */ +static QString +guessProductName() +{ + static bool tried = false; + static QString dmiProduct; + + if ( !tried ) + { + // yes validateHostnameText() but these files can be a mess + QRegExp dmirx( "[^a-zA-Z0-9]", Qt::CaseInsensitive ); + QFile dmiFile( QStringLiteral( "/sys/devices/virtual/dmi/id/product_name" ) ); + + if ( dmiFile.exists() && dmiFile.open( QIODevice::ReadOnly ) ) + { + dmiProduct = QString::fromLocal8Bit( dmiFile.readAll().simplified().data() ) + .toLower() + .replace( dmirx, " " ) + .remove( ' ' ); + } + if ( dmiProduct.isEmpty() ) + { + dmiProduct = QStringLiteral( "-pc" ); + } + tried = true; + } + return dmiProduct; +} void UsersPage::fillSuggestions() @@ -305,27 +337,9 @@ UsersPage::fillSuggestions() { if ( !cleanParts.isEmpty() && !cleanParts.first().isEmpty() ) { - - QString dmiProductName; QString hostnameSuggestion; - // yes validateHostnameText() but these files can be a mess - QRegExp dmirx( "[^a-zA-Z0-9]", Qt::CaseInsensitive ); - QFile dmiFile( QStringLiteral( "/sys/devices/virtual/dmi/id/product_name" ) ); - - if ( dmiFile.exists() && - dmiFile.open(QIODevice::ReadOnly)) - { - dmiProductName = QString::fromLocal8Bit( dmiFile.readAll().simplified().data() ) - .toLower().replace(dmirx, " ").remove(' '); - } - if ( !dmiProductName.isEmpty() ) - { - hostnameSuggestion = QString( "%1-%2" ).arg( cleanParts.first() ).arg( dmiProductName ); - } - else - { - hostnameSuggestion = QString( "%1-pc" ).arg( cleanParts.first() ); - } + QString productName = guessProductName(); + hostnameSuggestion = QString( "%1-%2" ).arg( cleanParts.first() ).arg( productName ); if ( HOSTNAME_RX.indexIn( hostnameSuggestion ) != -1 ) { ui->textBoxHostname->setText( hostnameSuggestion ); From b337a6b3f59a1533d5b62b510cce2dd15bf5973b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 11:46:05 +0100 Subject: [PATCH 17/78] [user] Apply coding style --- src/modules/users/UsersPage.cpp | 14 ++++++-------- src/modules/users/UsersViewStep.cpp | 3 ++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index ac6ff974c..c5c6ef8d4 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -99,14 +99,12 @@ UsersPage::UsersPage( QWidget* parent ) connect( ui->textBoxUserVerifiedPassword, &QLineEdit::textChanged, this, &UsersPage::onPasswordTextChanged ); connect( ui->textBoxRootPassword, &QLineEdit::textChanged, this, &UsersPage::onRootPasswordTextChanged ); connect( ui->textBoxVerifiedRootPassword, &QLineEdit::textChanged, this, &UsersPage::onRootPasswordTextChanged ); - connect( ui->checkBoxValidatePassword, &QCheckBox::stateChanged, this, [this]( int ) - { + connect( ui->checkBoxValidatePassword, &QCheckBox::stateChanged, this, [this]( int ) { onPasswordTextChanged( ui->textBoxUserPassword->text() ); onRootPasswordTextChanged( ui->textBoxRootPassword->text() ); checkReady( isReady() ); } ); - connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( int checked ) - { + connect( ui->checkBoxReusePassword, &QCheckBox::stateChanged, this, [this]( int checked ) { ui->labelChooseRootPassword->setVisible( !checked ); ui->labelRootPassword->setVisible( !checked ); ui->labelRootPasswordError->setVisible( !checked ); @@ -560,10 +558,10 @@ UsersPage::addPasswordCheck( const QString& key, const QVariant& value ) { if ( value.toBool() ) { - m_passwordChecks.push_back( PasswordCheck( - []() { return QCoreApplication::translate( "PWQ", "Password is empty" ); }, - []( const QString& s ) { return !s.isEmpty(); }, - PasswordCheck::Weight( 1 ) ) ); + m_passwordChecks.push_back( + PasswordCheck( []() { return QCoreApplication::translate( "PWQ", "Password is empty" ); }, + []( const QString& s ) { return !s.isEmpty(); }, + PasswordCheck::Weight( 1 ) ) ); } } #ifdef CHECK_PWQUALITY diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index b898f00c8..0f42d1476 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -174,7 +174,8 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } m_widget->setPasswordCheckboxVisible( CalamaresUtils::getBool( configurationMap, "allowWeakPasswords", false ) ); - m_widget->setValidatePasswordDefault( !CalamaresUtils::getBool( configurationMap, "allowWeakPasswordsDefault", false) ); + m_widget->setValidatePasswordDefault( + !CalamaresUtils::getBool( configurationMap, "allowWeakPasswordsDefault", false ) ); QString shell( QLatin1String( "/bin/bash" ) ); // as if it's not set at all if ( configurationMap.contains( "userShell" ) ) From 695b88b8a72d0d233b57d7d6b5ef22d5fced67c8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 12:31:53 +0100 Subject: [PATCH 18/78] [users] Tidy up hostname creation - Use the createTargetFile() convenience functions to do the actual work. - This probably involves more copying around of buffers, since it's creating one big QString and sending that off, rather than writing little chunks to a file, but I feel this is worth the code simplification. - Drops all the error checking for creation, though, because the API for createTargetFile() lousy. --- src/modules/users/SetHostNameJob.cpp | 44 ++++++++++++---------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index b03d7a200..838288b4f 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -22,6 +22,7 @@ #include "GlobalStorage.h" #include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include @@ -71,43 +72,36 @@ SetHostNameJob::exec() return Calamares::JobResult::error( tr( "Internal Error" ) ); } - QFile hostfile( destDir + "/etc/hostname" ); + CalamaresUtils::System::instance()->createTargetFile( QStringLiteral( "/etc/hostname" ), + ( m_hostname + '\n' ).toUtf8() ); + +#if 0 if ( !hostfile.open( QFile::WriteOnly ) ) { cError() << "Can't write to hostname file"; return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); } +#endif - QTextStream hostfileout( &hostfile ); - hostfileout << m_hostname << "\n"; - hostfile.close(); + // The actual hostname gets substituted in at %1 + static const char etc_hosts[] = R"(# Host addresses +127.0.0.1 localhost +127.0.1.1 %1 +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +)"; - QFile hostsfile( destDir + "/etc/hosts" ); + CalamaresUtils::System::instance()->createTargetFile( QStringLiteral( "/etc/hosts" ), + QString( etc_hosts ).arg( m_hostname ).toUtf8() ); + +#if 0 if ( !hostsfile.open( QFile::WriteOnly ) ) { cError() << "Can't write to hosts file"; return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); } - - // We also need to write the appropriate entries for /etc/hosts - QTextStream hostsfileout( &hostsfile ); - // ipv4 support - hostsfileout << "127.0.0.1" - << "\t" - << "localhost" - << "\n"; - hostsfileout << "127.0.1.1" - << "\t" << m_hostname << "\n"; - // ipv6 support - hostsfileout << "::1" - << "\t" - << "localhost ip6-localhost ip6-loopback" - << "\n"; - hostsfileout << "ff02::1 ip6-allnodes" - << "\n" - << "ff02::2 ip6-allrouters" - << "\n"; - hostsfile.close(); +#endif return Calamares::JobResult::ok(); } From 2d7398161d3eb6fc20ac25de607cc22a321ddc8b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 12:52:37 +0100 Subject: [PATCH 19/78] [libcalamares] More detail for createTargetFile() - Return a result-object with statrus information and the path which was previously used (empty for "failures"). --- .../utils/CalamaresUtilsSystem.cpp | 12 +++--- src/libcalamares/utils/CalamaresUtilsSystem.h | 37 ++++++++++++++++++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index 61e05976a..8bd696bf0 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -293,19 +293,19 @@ System::targetPath( const QString& path ) const } } -QString +CreationResult System::createTargetFile( const QString& path, const QByteArray& contents ) const { QString completePath = targetPath( path ); if ( completePath.isEmpty() ) { - return QString(); + return CreationResult( CreationResult::Code::Invalid ); } QFile f( completePath ); if ( f.exists() ) { - return QString(); + return CreationResult( CreationResult::Code::AlreadyExists ); } QIODevice::OpenMode m = @@ -317,18 +317,18 @@ System::createTargetFile( const QString& path, const QByteArray& contents ) cons if ( !f.open( m ) ) { - return QString(); + return CreationResult( CreationResult::Code::Failed ); } if ( f.write( contents ) != contents.size() ) { f.close(); f.remove(); - return QString(); + return CreationResult( CreationResult::Code::Failed ); } f.close(); - return QFileInfo( f ).canonicalFilePath(); + return CreationResult( QFileInfo( f ).canonicalFilePath() ); } void diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.h b/src/libcalamares/utils/CalamaresUtilsSystem.h index ca8e0d797..900634a74 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.h +++ b/src/libcalamares/utils/CalamaresUtilsSystem.h @@ -84,6 +84,41 @@ public: } }; +/** @brief The result of a create*() action, for status + * + * A CreationResult has a status field, can be converted to bool + * (true only on success) and can report the full pathname of + * the thing created if it was successful. + */ +class CreationResult : public QPair< int, QString > +{ +public: + enum class Code : int + { + // These are "not failed", but only OK is a success + OK = 0, + AlreadyExists = 1, + // These are "failed" + Invalid = -1, + Failed = -2 + }; + + CreationResult( Code r ) + : QPair< int, QString >( static_cast< int >( r ), QString() ) + { + } + explicit CreationResult( const QString& path ) + : QPair< int, QString >( 0, path ) + { + } + + Code code() const { return static_cast< Code >( first ); } + QString path() const { return second; } + + bool failed() const { return first < 0; } + operator bool() const { return first == 0; } +}; + /** * @brief The System class is a singleton with utility functions that perform * system-specific operations. @@ -244,7 +279,7 @@ public: * root of the host system, or empty on failure. (Here, it is * possible to be canonical because the file exists). */ - DLLEXPORT QString createTargetFile( const QString& path, const QByteArray& contents ) const; + DLLEXPORT CreationResult createTargetFile( const QString& path, const QByteArray& contents ) const; /** @brief Remove a file from the target system. * From 274115c727fc0bd1f1315be87738abd04175b6a0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 13:07:29 +0100 Subject: [PATCH 20/78] [libcalamares] Update tests to reflect changed API --- src/libcalamares/utils/TestPaths.cpp | 5 ++++- src/modules/initramfs/InitramfsJob.cpp | 2 +- src/modules/initramfs/Tests.cpp | 24 +++++++++++++++--------- src/modules/machineid/Tests.cpp | 9 +++++++-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/libcalamares/utils/TestPaths.cpp b/src/libcalamares/utils/TestPaths.cpp index da67f9dd2..f24c7b61b 100644 --- a/src/libcalamares/utils/TestPaths.cpp +++ b/src/libcalamares/utils/TestPaths.cpp @@ -117,7 +117,10 @@ TestPaths::testTargetPath() void TestPaths::testCreateTarget() { - QCOMPARE( m_system->createTargetFile( testFile, "Hello" ), QString( absFile ) ); // Success + auto r = m_system->createTargetFile( testFile, "Hello" ); + QVERIFY( !r.failed() ); + QVERIFY( r ); + QCOMPARE( r.path(), QString( absFile ) ); // Success QFileInfo fi( absFile ); QVERIFY( fi.exists() ); diff --git a/src/modules/initramfs/InitramfsJob.cpp b/src/modules/initramfs/InitramfsJob.cpp index af8e07ca7..468047c45 100644 --- a/src/modules/initramfs/InitramfsJob.cpp +++ b/src/modules/initramfs/InitramfsJob.cpp @@ -54,7 +54,7 @@ InitramfsJob::exec() // First make sure we generate a safe initramfs with suitable permissions. static const char confFile[] = "/etc/initramfs-tools/conf.d/calamares-safe-initramfs.conf"; static const char contents[] = "UMASK=0077\n"; - if ( CalamaresUtils::System::instance()->createTargetFile( confFile, QByteArray( contents ) ).isEmpty() ) + if ( CalamaresUtils::System::instance()->createTargetFile( confFile, QByteArray( contents ) ).failed() ) { cWarning() << Logger::SubEntry << "Could not configure safe UMASK for initramfs."; // But continue anyway. diff --git a/src/modules/initramfs/Tests.cpp b/src/modules/initramfs/Tests.cpp index 936c94097..39d2abeaa 100644 --- a/src/modules/initramfs/Tests.cpp +++ b/src/modules/initramfs/Tests.cpp @@ -57,9 +57,12 @@ void InitramfsTests::cleanup() void InitramfsTests::testCreateHostFile() { - + CalamaresUtils::System s( false ); // don't chroot - QString path = s.createTargetFile( confFile, QByteArray( contents ) ); + auto r = s.createTargetFile( confFile, QByteArray( contents ) ); + QVERIFY( !r.failed() ); + QVERIFY( r ); + QString path = r.path(); QVERIFY( !path.isEmpty() ); QCOMPARE( path, confFile ); // don't chroot, so path create relative to / QVERIFY( QFile::exists( confFile ) ); @@ -67,30 +70,33 @@ void InitramfsTests::testCreateHostFile() QFileInfo fi( confFile ); QVERIFY( fi.exists() ); QCOMPARE( fi.size(), sizeof( contents )-1 ); // don't count trailing NUL - + QFile::remove( confFile ); } void InitramfsTests::testCreateTargetFile() { static const char short_confFile[] = "/calamares-safe-umask"; - + CalamaresUtils::System s( true ); - QString path = s.createTargetFile( short_confFile, QByteArray( contents ) ); + auto r = s.createTargetFile( short_confFile, QByteArray( contents ) ); + QVERIFY( r.failed() ); + QVERIFY( !r ); + QString path = r.path(); QVERIFY( path.isEmpty() ); // because no rootmountpoint is set - + Calamares::JobQueue j; j.globalStorage()->insert( "rootMountPoint", "/tmp" ); - + path = s.createTargetFile( short_confFile, QByteArray( contents ) ); - QVERIFY( path.endsWith( short_confFile ) ); // chroot, so path create relative to + QVERIFY( path.endsWith( short_confFile ) ); // chroot, so path create relative to QVERIFY( path.startsWith( "/tmp/" ) ); QVERIFY( QFile::exists( path ) ); QFileInfo fi( path ); QVERIFY( fi.exists() ); QCOMPARE( fi.size(), sizeof( contents )-1 ); // don't count trailing NUL - + QFile::remove( path ); } diff --git a/src/modules/machineid/Tests.cpp b/src/modules/machineid/Tests.cpp index 53abd0482..9ee3b3b6e 100644 --- a/src/modules/machineid/Tests.cpp +++ b/src/modules/machineid/Tests.cpp @@ -122,8 +122,13 @@ MachineIdTests::testJob() gs->insert( "rootMountPoint", "/tmp" ); // Prepare part of the target filesystem - QVERIFY( system->createTargetDirs("/etc") ); - QVERIFY( !(system->createTargetFile( "/etc/machine-id", "Hello" ).isEmpty() ) ); + { + QVERIFY( system->createTargetDirs("/etc") ); + auto r = system->createTargetFile( "/etc/machine-id", "Hello" ); + QVERIFY( !r.failed() ); + QVERIFY( r ); + QVERIFY( !r.path().isEmpty() ); + } MachineIdJob job( nullptr ); QVERIFY( !job.prettyName().isEmpty() ); From f6526f7d9f0c98616c159f34e2941d7de7b88ec0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 13:21:16 +0100 Subject: [PATCH 21/78] [libcalamares] Add some tests for CreationResult - More important is the compiler warning that will show up if we add more failure states. --- src/libcalamares/utils/TestPaths.cpp | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/libcalamares/utils/TestPaths.cpp b/src/libcalamares/utils/TestPaths.cpp index f24c7b61b..612c8f97d 100644 --- a/src/libcalamares/utils/TestPaths.cpp +++ b/src/libcalamares/utils/TestPaths.cpp @@ -46,6 +46,7 @@ private Q_SLOTS: void init(); void cleanupTestCase(); + void testCreationResult(); void testTargetPath(); void testCreateTarget(); void testCreateTargetBasedirs(); @@ -95,6 +96,42 @@ TestPaths::init() m_gs->insert( "rootMountPoint", "/tmp" ); } +void TestPaths::testCreationResult() +{ + using Code = CalamaresUtils::CreationResult::Code; + + for( auto c : { Code::OK, Code::AlreadyExists, Code::Failed, Code::Invalid } ) + { + auto r = CalamaresUtils::CreationResult( c ); + QVERIFY( r.path().isEmpty() ); + QCOMPARE( r.path(), QString() ); + // Get a warning from Clang if we're not covering everything + switch( r.code() ) + { + case Code::OK: + QVERIFY( !r.failed() ); + QVERIFY( r ); + break; + case Code::AlreadyExists: + QVERIFY( !r.failed() ); + QVERIFY( !r ); + break; + case Code::Failed: + case Code::Invalid: + QVERIFY( r.failed() ); + QVERIFY( !r ); + break; + } + } + + QString path( "/etc/os-release" ); + auto r = CalamaresUtils::CreationResult( path ); + QVERIFY( !r.failed() ); + QVERIFY( r ); + QCOMPARE( r.code(), Code::OK ); + QCOMPARE( r.path(), path ); +} + void TestPaths::testTargetPath() From 781322ab41be9e0a2f0579bb5011307af6b1e0ce Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 13:23:19 +0100 Subject: [PATCH 22/78] [libcalamares] Use more descriptive variable name - If the test failed, you'd get a cryptic message like FAIL! : NetworkTests::testPing() 'r' returned FALSE. () So rename the variable so the failure mode is more obvious. (Could have used QVERIFY2() instead, this is simpler) --- src/libcalamares/network/Tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/network/Tests.cpp b/src/libcalamares/network/Tests.cpp index 3a15b3c59..830545b96 100644 --- a/src/libcalamares/network/Tests.cpp +++ b/src/libcalamares/network/Tests.cpp @@ -47,6 +47,6 @@ NetworkTests::testPing() using namespace CalamaresUtils::Network; Logger::setupLogLevel( Logger::LOGVERBOSE ); auto& nam = Manager::instance(); - auto r = nam.synchronousPing( QUrl( "https://www.kde.org" ), RequestOptions( RequestOptions::FollowRedirect ) ); - QVERIFY( r ); + auto canPing_www_kde_org = nam.synchronousPing( QUrl( "https://www.kde.org" ), RequestOptions( RequestOptions::FollowRedirect ) ); + QVERIFY( canPing_www_kde_org ); } From 90f79b06928a3fa3b60e8c17101cc0a078d70cff Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Feb 2020 13:27:49 +0100 Subject: [PATCH 23/78] [users] Restore error-checking to set-hostname code - Use the new CreationResult code for compact results --- src/modules/users/SetHostNameJob.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index 838288b4f..41da239d5 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -72,16 +72,13 @@ SetHostNameJob::exec() return Calamares::JobResult::error( tr( "Internal Error" ) ); } - CalamaresUtils::System::instance()->createTargetFile( QStringLiteral( "/etc/hostname" ), - ( m_hostname + '\n' ).toUtf8() ); - -#if 0 - if ( !hostfile.open( QFile::WriteOnly ) ) + if ( CalamaresUtils::System::instance() + ->createTargetFile( QStringLiteral( "/etc/hostname" ), ( m_hostname + '\n' ).toUtf8() ) + .failed() ) { cError() << "Can't write to hostname file"; return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); } -#endif // The actual hostname gets substituted in at %1 static const char etc_hosts[] = R"(# Host addresses @@ -92,16 +89,13 @@ ff02::1 ip6-allnodes ff02::2 ip6-allrouters )"; - CalamaresUtils::System::instance()->createTargetFile( QStringLiteral( "/etc/hosts" ), - QString( etc_hosts ).arg( m_hostname ).toUtf8() ); - -#if 0 - if ( !hostsfile.open( QFile::WriteOnly ) ) + if ( CalamaresUtils::System::instance() + ->createTargetFile( QStringLiteral( "/etc/hosts" ), QString( etc_hosts ).arg( m_hostname ).toUtf8() ) + .failed() ) { cError() << "Can't write to hosts file"; return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); } -#endif return Calamares::JobResult::ok(); } From b582c27bf446d47172790e8275e206912f54bc46 Mon Sep 17 00:00:00 2001 From: Yuri Chornoivan Date: Sun, 16 Feb 2020 14:09:30 +0200 Subject: [PATCH 24/78] Fix minor typo Many thanks in advance for reviewing. --- src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp b/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp index 9997cc185..90d64d5a6 100644 --- a/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp +++ b/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp @@ -205,7 +205,7 @@ LuksBootKeyFileJob::exec() if ( !setupLuks( d ) ) return Calamares::JobResult::error( tr( "Encrypted rootfs setup error" ), - tr( "Could configure LUKS key file on partition %1." ).arg( d.device ) ); + tr( "Could not configure LUKS key file on partition %1." ).arg( d.device ) ); } return Calamares::JobResult::ok(); From ea82a26dae4c3e0e6386ce719a3c1f98800cc3fe Mon Sep 17 00:00:00 2001 From: Yuri Chornoivan Date: Sun, 16 Feb 2020 14:12:48 +0200 Subject: [PATCH 25/78] Fix typo:; partitons -> partitions Many thanks in advance for reviewing. --- src/modules/partition/gui/PartitionViewStep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/gui/PartitionViewStep.cpp b/src/modules/partition/gui/PartitionViewStep.cpp index 1bb7f64fd..4b16d807a 100644 --- a/src/modules/partition/gui/PartitionViewStep.cpp +++ b/src/modules/partition/gui/PartitionViewStep.cpp @@ -648,7 +648,7 @@ PartitionViewStep::checkRequirements() { QLatin1String( "partitions" ), []{ return tr( "has at least one disk device available." ); }, - []{ return tr( "There are no partitons to install on." ); }, + []{ return tr( "There are no partitions to install on." ); }, m_core->deviceModel()->rowCount() > 0, // satisfied #ifdef DEBUG_PARTITION_UNSAFE false // optional From 9a7465bfd5d941f06cc4c252ee1dac8b21fed3ba Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 10:42:54 +0100 Subject: [PATCH 26/78] [users] Refactor writing-hostname and writing-hosts - Move to separate functions, as prep-work for making the actions configurable (and optional). --- src/modules/users/SetHostNameJob.cpp | 43 ++++++++++++++++++---------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index 41da239d5..868c8f852 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -54,6 +54,32 @@ SetHostNameJob::prettyStatusMessage() const return tr( "Setting hostname %1." ).arg( m_hostname ); } +static bool +setFileHostname( const QString& hostname ) +{ + return !( CalamaresUtils::System::instance() + ->createTargetFile( QStringLiteral( "/etc/hostname" ), ( hostname + '\n' ).toUtf8() ) + .failed() ); +} + +static bool +writeFileEtcHosts( const QString& hostname ) +{ + // The actual hostname gets substituted in at %1 + static const char etc_hosts[] = R"(# Host addresses +127.0.0.1 localhost +127.0.1.1 %1 +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +)"; + + return !( CalamaresUtils::System::instance() + ->createTargetFile( QStringLiteral( "/etc/hosts" ), QString( etc_hosts ).arg( hostname ).toUtf8() ) + .failed() ); +} + + Calamares::JobResult SetHostNameJob::exec() { @@ -72,26 +98,13 @@ SetHostNameJob::exec() return Calamares::JobResult::error( tr( "Internal Error" ) ); } - if ( CalamaresUtils::System::instance() - ->createTargetFile( QStringLiteral( "/etc/hostname" ), ( m_hostname + '\n' ).toUtf8() ) - .failed() ) + if ( !setFileHostname( m_hostname ) ) { cError() << "Can't write to hostname file"; return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); } - // The actual hostname gets substituted in at %1 - static const char etc_hosts[] = R"(# Host addresses -127.0.0.1 localhost -127.0.1.1 %1 -::1 localhost ip6-localhost ip6-loopback -ff02::1 ip6-allnodes -ff02::2 ip6-allrouters -)"; - - if ( CalamaresUtils::System::instance() - ->createTargetFile( QStringLiteral( "/etc/hosts" ), QString( etc_hosts ).arg( m_hostname ).toUtf8() ) - .failed() ) + if ( !writeFileEtcHosts( m_hostname ) ) { cError() << "Can't write to hosts file"; return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); From 44bf0a5d6df55f8c6aaa908e5c5addc76d43e7db Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 10:57:41 +0100 Subject: [PATCH 27/78] [users] Add method for using hostnamed SEE #1140 --- src/modules/users/CMakeLists.txt | 3 ++- src/modules/users/SetHostNameJob.cpp | 29 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/modules/users/CMakeLists.txt b/src/modules/users/CMakeLists.txt index d0e7b6d9d..944433f79 100644 --- a/src/modules/users/CMakeLists.txt +++ b/src/modules/users/CMakeLists.txt @@ -1,4 +1,4 @@ -find_package( Qt5 COMPONENTS Core REQUIRED ) +find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Core DBus Network ) find_package( Crypt REQUIRED ) # Add optional libraries here @@ -36,6 +36,7 @@ calamares_add_plugin( users calamaresui ${CRYPT_LIBRARIES} ${USER_EXTRA_LIB} + Qt5::DBus SHARED_LIB ) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index 868c8f852..de98854ec 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -27,6 +27,9 @@ #include #include +#include +#include +#include SetHostNameJob::SetHostNameJob( const QString& hostname ) : Calamares::Job() @@ -79,6 +82,32 @@ ff02::2 ip6-allrouters .failed() ); } +static void +setSystemdHostname( const QString& hostname ) +{ + QDBusInterface hostnamed( "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + QDBusConnection::systemBus() ); + + // Static, writes /etc/hostname + { + QDBusReply< uint > r = hostnamed.call( "SetStaticHostname", hostname, false ); + if ( !r.isValid() ) + { + cWarning() << "Could not set hostname through org.freedesktop.hostname1.SetStaticHostname." << r.error(); + } + } + // Dynamic, updates kernel + { + QDBusReply< uint > r = hostnamed.call( "SetHostname", hostname, false ); + if ( !r.isValid() ) + { + cWarning() << "Could not set hostname through org.freedesktop.hostname1.SetHostname." << r.error(); + } + } +} + Calamares::JobResult SetHostNameJob::exec() From aaa6f6bd55ea64dd29cccdf55c296d4b5ce8e17d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 11:32:28 +0100 Subject: [PATCH 28/78] [libcalamaresui] Drop UiDllMacro.h - The scattering of DLL export macro's is kind of useless; there are several headers, and then the export macro isn't even applied consistently. Just drop the one for UI exports, which was only used in libcalamaresui. --- src/calamares/CMakeLists.txt | 2 -- src/libcalamaresui/Branding.h | 4 +-- src/libcalamaresui/CMakeLists.txt | 2 +- src/libcalamaresui/UiDllMacro.h | 32 ------------------- src/libcalamaresui/ViewManager.h | 4 +-- .../modulesystem/CppJobModule.h | 4 +-- src/libcalamaresui/modulesystem/Module.h | 4 +-- .../modulesystem/ProcessJobModule.h | 4 +-- .../modulesystem/PythonJobModule.h | 4 +-- .../modulesystem/PythonQtViewModule.h | 4 +-- src/libcalamaresui/modulesystem/ViewModule.h | 4 +-- src/libcalamaresui/utils/CalamaresUtilsGui.h | 22 ++++++------- src/libcalamaresui/utils/ImageRegistry.h | 4 +-- src/libcalamaresui/viewpages/ViewStep.h | 4 +-- 14 files changed, 32 insertions(+), 66 deletions(-) delete mode 100644 src/libcalamaresui/UiDllMacro.h diff --git a/src/calamares/CMakeLists.txt b/src/calamares/CMakeLists.txt index a55e26b6d..9327af8e3 100644 --- a/src/calamares/CMakeLists.txt +++ b/src/calamares/CMakeLists.txt @@ -1,5 +1,3 @@ -add_definitions( -DUIDLLEXPORT_PRO ) - set( calamaresSources main.cpp CalamaresApplication.cpp diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index e3952881e..4c051981c 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -22,7 +22,7 @@ #ifndef BRANDING_H #define BRANDING_H -#include "UiDllMacro.h" +#include "DllMacro.h" #include "utils/NamedSuffix.h" @@ -40,7 +40,7 @@ namespace Calamares class GlobalStorage; -class UIDLLEXPORT Branding : public QObject +class DLLEXPORT Branding : public QObject { Q_OBJECT public: diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index c603ca22d..9f87ed009 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -66,7 +66,7 @@ endif() calamares_add_library( calamaresui SOURCES ${calamaresui_SOURCES} - EXPORT_MACRO UIDLLEXPORT_PRO + EXPORT_MACRO DLLEXPORT_PRO LINK_PRIVATE_LIBRARIES ${OPTIONAL_PYTHON_LIBRARIES} LINK_LIBRARIES diff --git a/src/libcalamaresui/UiDllMacro.h b/src/libcalamaresui/UiDllMacro.h deleted file mode 100644 index 3064ca68c..000000000 --- a/src/libcalamaresui/UiDllMacro.h +++ /dev/null @@ -1,32 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Teo Mrnjavac - * - * 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 UIDLLMACRO_H -#define UIDLLMACRO_H - -#include - -#ifndef UIDLLEXPORT -#if defined( UIDLLEXPORT_PRO ) -#define UIDLLEXPORT Q_DECL_EXPORT -#else -#define UIDLLEXPORT Q_DECL_IMPORT -#endif -#endif - -#endif diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index fca74a367..50838f780 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -20,7 +20,7 @@ #ifndef VIEWMANAGER_H #define VIEWMANAGER_H -#include "UiDllMacro.h" +#include "DllMacro.h" #include "viewpages/ViewStep.h" #include @@ -33,7 +33,7 @@ namespace Calamares * @brief The ViewManager class handles progression through view pages. * @note Singleton object, only use through ViewManager::instance(). */ -class UIDLLEXPORT ViewManager : public QObject +class DLLEXPORT ViewManager : public QObject { Q_OBJECT public: diff --git a/src/libcalamaresui/modulesystem/CppJobModule.h b/src/libcalamaresui/modulesystem/CppJobModule.h index feb0f22bb..758b44459 100644 --- a/src/libcalamaresui/modulesystem/CppJobModule.h +++ b/src/libcalamaresui/modulesystem/CppJobModule.h @@ -22,14 +22,14 @@ #define CALAMARES_CPPJOBMODULE_H #include "Module.h" -#include "UiDllMacro.h" +#include "DllMacro.h" class QPluginLoader; namespace Calamares { -class UIDLLEXPORT CppJobModule : public Module +class DLLEXPORT CppJobModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/Module.h b/src/libcalamaresui/modulesystem/Module.h index bf2f1cb5d..4ebbdf2a2 100644 --- a/src/libcalamaresui/modulesystem/Module.h +++ b/src/libcalamaresui/modulesystem/Module.h @@ -22,7 +22,7 @@ #include "Job.h" #include "Requirement.h" -#include "UiDllMacro.h" +#include "DllMacro.h" #include "modulesystem/Descriptor.h" #include "modulesystem/InstanceKey.h" @@ -40,7 +40,7 @@ namespace Calamares * takes care of creating an object of the correct type starting from a module * descriptor structure. */ -class UIDLLEXPORT Module +class DLLEXPORT Module { public: /** diff --git a/src/libcalamaresui/modulesystem/ProcessJobModule.h b/src/libcalamaresui/modulesystem/ProcessJobModule.h index 96fb2ed47..31e3b1219 100644 --- a/src/libcalamaresui/modulesystem/ProcessJobModule.h +++ b/src/libcalamaresui/modulesystem/ProcessJobModule.h @@ -22,14 +22,14 @@ #include "Module.h" -#include "UiDllMacro.h" +#include "DllMacro.h" #include namespace Calamares { -class UIDLLEXPORT ProcessJobModule : public Module +class DLLEXPORT ProcessJobModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/PythonJobModule.h b/src/libcalamaresui/modulesystem/PythonJobModule.h index 8fa137f71..1d70b5f6c 100644 --- a/src/libcalamaresui/modulesystem/PythonJobModule.h +++ b/src/libcalamaresui/modulesystem/PythonJobModule.h @@ -21,12 +21,12 @@ #include "Module.h" -#include "UiDllMacro.h" +#include "DllMacro.h" namespace Calamares { -class UIDLLEXPORT PythonJobModule : public Module +class DLLEXPORT PythonJobModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/PythonQtViewModule.h b/src/libcalamaresui/modulesystem/PythonQtViewModule.h index 6ebb5c433..eeee69a78 100644 --- a/src/libcalamaresui/modulesystem/PythonQtViewModule.h +++ b/src/libcalamaresui/modulesystem/PythonQtViewModule.h @@ -20,14 +20,14 @@ #define CALAMARES_PYTHONQTVIEWMODULE_H #include "Module.h" -#include "UiDllMacro.h" +#include "DllMacro.h" namespace Calamares { class ViewStep; -class UIDLLEXPORT PythonQtViewModule : public Module +class DLLEXPORT PythonQtViewModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/ViewModule.h b/src/libcalamaresui/modulesystem/ViewModule.h index e9db1347b..dfe9bed92 100644 --- a/src/libcalamaresui/modulesystem/ViewModule.h +++ b/src/libcalamaresui/modulesystem/ViewModule.h @@ -21,7 +21,7 @@ #define CALAMARES_VIEWMODULE_H #include "Module.h" -#include "UiDllMacro.h" +#include "DllMacro.h" class QPluginLoader; @@ -30,7 +30,7 @@ namespace Calamares class ViewStep; -class UIDLLEXPORT ViewModule : public Module +class DLLEXPORT ViewModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/utils/CalamaresUtilsGui.h b/src/libcalamaresui/utils/CalamaresUtilsGui.h index 0c10dcc30..884e603e3 100644 --- a/src/libcalamaresui/utils/CalamaresUtilsGui.h +++ b/src/libcalamaresui/utils/CalamaresUtilsGui.h @@ -20,7 +20,7 @@ #ifndef CALAMARESUTILSGUI_H #define CALAMARESUTILSGUI_H -#include "UiDllMacro.h" +#include "DllMacro.h" #include #include @@ -83,7 +83,7 @@ enum ImageMode * @param size the target pixmap size (default: original SVG size). * @return the new pixmap. */ -UIDLLEXPORT QPixmap defaultPixmap( ImageType type, +DLLEXPORT QPixmap defaultPixmap( ImageType type, ImageMode mode = CalamaresUtils::Original, const QSize& size = QSize( 0, 0 ) ); @@ -95,27 +95,27 @@ UIDLLEXPORT QPixmap defaultPixmap( ImageType type, * @return the transformed pixmap. * This one is currently unused. */ -UIDLLEXPORT QPixmap createRoundedImage( const QPixmap& avatar, const QSize& size, float frameWidthPct = 0.20f ); +DLLEXPORT QPixmap createRoundedImage( const QPixmap& avatar, const QSize& size, float frameWidthPct = 0.20f ); /** * @brief unmarginLayout recursively walks the QLayout tree and removes all margins. * @param layout the layout to unmargin. */ -UIDLLEXPORT void unmarginLayout( QLayout* layout ); +DLLEXPORT void unmarginLayout( QLayout* layout ); /** * @brief clearLayout recursively walks the QLayout tree and deletes all the child * widgets and layouts. * @param layout the layout to clear. */ -UIDLLEXPORT void clearLayout( QLayout* layout ); +DLLEXPORT void clearLayout( QLayout* layout ); -UIDLLEXPORT void setDefaultFontSize( int points ); -UIDLLEXPORT int defaultFontSize(); // in points -UIDLLEXPORT int defaultFontHeight(); // in pixels, DPI-specific -UIDLLEXPORT QFont defaultFont(); -UIDLLEXPORT QFont largeFont(); -UIDLLEXPORT QSize defaultIconSize(); +DLLEXPORT void setDefaultFontSize( int points ); +DLLEXPORT int defaultFontSize(); // in points +DLLEXPORT int defaultFontHeight(); // in pixels, DPI-specific +DLLEXPORT QFont defaultFont(); +DLLEXPORT QFont largeFont(); +DLLEXPORT QSize defaultIconSize(); /** * @brief Size constants for the main Calamares window. diff --git a/src/libcalamaresui/utils/ImageRegistry.h b/src/libcalamaresui/utils/ImageRegistry.h index 454cb500d..a7d04fa9a 100644 --- a/src/libcalamaresui/utils/ImageRegistry.h +++ b/src/libcalamaresui/utils/ImageRegistry.h @@ -28,10 +28,10 @@ #include -#include "UiDllMacro.h" +#include "DllMacro.h" #include "utils/CalamaresUtilsGui.h" -class UIDLLEXPORT ImageRegistry +class DLLEXPORT ImageRegistry { public: static ImageRegistry* instance(); diff --git a/src/libcalamaresui/viewpages/ViewStep.h b/src/libcalamaresui/viewpages/ViewStep.h index c5903d6f5..55b2e200a 100644 --- a/src/libcalamaresui/viewpages/ViewStep.h +++ b/src/libcalamaresui/viewpages/ViewStep.h @@ -21,7 +21,7 @@ #define VIEWSTEP_H #include "Job.h" -#include "UiDllMacro.h" +#include "DllMacro.h" #include "modulesystem/InstanceKey.h" #include "modulesystem/Requirement.h" @@ -45,7 +45,7 @@ namespace Calamares * (which shows all of the things which have been collected to be done in the * next exec-step) through prettyStatus() and createSummaryWidget(). */ -class UIDLLEXPORT ViewStep : public QObject +class DLLEXPORT ViewStep : public QObject { Q_OBJECT public: From b0445490138dbd29f4698a938091bd59ea4a7143 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 11:37:35 +0100 Subject: [PATCH 29/78] [libcalamares] Merge PluginDllMacro.h into DllMacro.h - Let's just have one header definining export- and visibility- macros for Calamares. They are still selected based on the export flags (*_PRO), just defined in one header instead of two. --- src/libcalamares/DllMacro.h | 8 +++++ src/libcalamares/PluginDllMacro.h | 32 ------------------- .../contextualprocess/ContextualProcessJob.h | 2 +- src/modules/dracutlukscfg/DracutLuksCfgJob.h | 2 +- src/modules/dummycpp/DummyCppJob.h | 2 +- src/modules/finished/FinishedViewStep.h | 2 +- src/modules/fsresizer/ResizeFSJob.h | 2 +- src/modules/hostinfo/HostInfoJob.h | 2 +- src/modules/initcpio/InitcpioJob.h | 2 +- src/modules/initramfs/InitramfsJob.h | 2 +- .../InteractiveTerminalViewStep.h | 2 +- src/modules/keyboard/KeyboardViewStep.h | 2 +- src/modules/license/LicenseViewStep.h | 2 +- src/modules/locale/LocaleViewStep.h | 2 +- .../luksbootkeyfile/LuksBootKeyFileJob.h | 2 +- src/modules/machineid/MachineIdJob.h | 2 +- src/modules/netinstall/NetInstallViewStep.h | 2 +- src/modules/notesqml/NotesQmlViewStep.h | 2 +- src/modules/oemid/OEMViewStep.h | 2 +- .../packagechooser/PackageChooserViewStep.h | 2 +- src/modules/partition/gui/PartitionViewStep.h | 2 +- src/modules/plasmalnf/PlasmaLnfViewStep.h | 2 +- src/modules/preservefiles/PreserveFiles.h | 2 +- src/modules/shellprocess/ShellProcessJob.h | 2 +- src/modules/summary/SummaryViewStep.h | 2 +- src/modules/tracking/TrackingViewStep.h | 2 +- src/modules/users/UsersViewStep.h | 2 +- src/modules/webview/WebViewStep.h | 2 +- src/modules/welcome/WelcomeViewStep.h | 2 +- src/modules/welcomeq/WelcomeQmlViewStep.h | 2 +- 30 files changed, 36 insertions(+), 60 deletions(-) delete mode 100644 src/libcalamares/PluginDllMacro.h diff --git a/src/libcalamares/DllMacro.h b/src/libcalamares/DllMacro.h index d3e1c8098..865d91d57 100644 --- a/src/libcalamares/DllMacro.h +++ b/src/libcalamares/DllMacro.h @@ -29,4 +29,12 @@ #endif #endif +#ifndef PLUGINDLLEXPORT +#if defined( PLUGINDLLEXPORT_PRO ) +#define PLUGINDLLEXPORT Q_DECL_EXPORT +#else +#define PLUGINDLLEXPORT Q_DECL_IMPORT +#endif +#endif + #endif diff --git a/src/libcalamares/PluginDllMacro.h b/src/libcalamares/PluginDllMacro.h deleted file mode 100644 index d790230b9..000000000 --- a/src/libcalamares/PluginDllMacro.h +++ /dev/null @@ -1,32 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Teo Mrnjavac - * - * 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 PLUGINDLLMACRO_H -#define PLUGINDLLMACRO_H - -#include - -#ifndef PLUGINDLLEXPORT -#if defined( PLUGINDLLEXPORT_PRO ) -#define PLUGINDLLEXPORT Q_DECL_EXPORT -#else -#define PLUGINDLLEXPORT Q_DECL_IMPORT -#endif -#endif - -#endif diff --git a/src/modules/contextualprocess/ContextualProcessJob.h b/src/modules/contextualprocess/ContextualProcessJob.h index 2efbc5082..3a252d2d3 100644 --- a/src/modules/contextualprocess/ContextualProcessJob.h +++ b/src/modules/contextualprocess/ContextualProcessJob.h @@ -23,7 +23,7 @@ #include #include "CppJob.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "utils/PluginFactory.h" diff --git a/src/modules/dracutlukscfg/DracutLuksCfgJob.h b/src/modules/dracutlukscfg/DracutLuksCfgJob.h index e9e5a54a2..ccf0adb70 100644 --- a/src/modules/dracutlukscfg/DracutLuksCfgJob.h +++ b/src/modules/dracutlukscfg/DracutLuksCfgJob.h @@ -27,7 +27,7 @@ #include -#include +#include class PLUGINDLLEXPORT DracutLuksCfgJob : public Calamares::CppJob { diff --git a/src/modules/dummycpp/DummyCppJob.h b/src/modules/dummycpp/DummyCppJob.h index 4a79d0378..c60b01d57 100644 --- a/src/modules/dummycpp/DummyCppJob.h +++ b/src/modules/dummycpp/DummyCppJob.h @@ -27,7 +27,7 @@ #include -#include +#include class PLUGINDLLEXPORT DummyCppJob : public Calamares::CppJob { diff --git a/src/modules/finished/FinishedViewStep.h b/src/modules/finished/FinishedViewStep.h index 7b3881099..2df37e9b6 100644 --- a/src/modules/finished/FinishedViewStep.h +++ b/src/modules/finished/FinishedViewStep.h @@ -25,7 +25,7 @@ #include "utils/PluginFactory.h" #include "viewpages/ViewStep.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" class FinishedPage; diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 76ca6c219..985942b99 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -27,7 +27,7 @@ #include "partition/PartitionSize.h" #include "utils/PluginFactory.h" -#include +#include class CoreBackend; // From KPMCore class Device; // From KPMCore diff --git a/src/modules/hostinfo/HostInfoJob.h b/src/modules/hostinfo/HostInfoJob.h index fa3342192..5db169b0e 100644 --- a/src/modules/hostinfo/HostInfoJob.h +++ b/src/modules/hostinfo/HostInfoJob.h @@ -20,7 +20,7 @@ #define HOSTINFOJOB_H #include "CppJob.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "utils/PluginFactory.h" #include diff --git a/src/modules/initcpio/InitcpioJob.h b/src/modules/initcpio/InitcpioJob.h index 11358d749..cdc48f6ce 100644 --- a/src/modules/initcpio/InitcpioJob.h +++ b/src/modules/initcpio/InitcpioJob.h @@ -20,7 +20,7 @@ #define INITCPIOJOB_H #include "CppJob.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "utils/PluginFactory.h" #include diff --git a/src/modules/initramfs/InitramfsJob.h b/src/modules/initramfs/InitramfsJob.h index 9eeb81fea..3239c6929 100644 --- a/src/modules/initramfs/InitramfsJob.h +++ b/src/modules/initramfs/InitramfsJob.h @@ -20,7 +20,7 @@ #define INITRAMFSJOB_H #include "CppJob.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "utils/PluginFactory.h" #include diff --git a/src/modules/interactiveterminal/InteractiveTerminalViewStep.h b/src/modules/interactiveterminal/InteractiveTerminalViewStep.h index 55486691d..f0af35d3c 100644 --- a/src/modules/interactiveterminal/InteractiveTerminalViewStep.h +++ b/src/modules/interactiveterminal/InteractiveTerminalViewStep.h @@ -25,7 +25,7 @@ #include #include -#include +#include class InteractiveTerminalPage; diff --git a/src/modules/keyboard/KeyboardViewStep.h b/src/modules/keyboard/KeyboardViewStep.h index a5bdd579e..9f362e116 100644 --- a/src/modules/keyboard/KeyboardViewStep.h +++ b/src/modules/keyboard/KeyboardViewStep.h @@ -25,7 +25,7 @@ #include #include -#include +#include class KeyboardPage; diff --git a/src/modules/license/LicenseViewStep.h b/src/modules/license/LicenseViewStep.h index 957110f3d..cc1a92896 100644 --- a/src/modules/license/LicenseViewStep.h +++ b/src/modules/license/LicenseViewStep.h @@ -20,7 +20,7 @@ #ifndef LICENSEPAGEPLUGIN_H #define LICENSEPAGEPLUGIN_H -#include +#include #include #include diff --git a/src/modules/locale/LocaleViewStep.h b/src/modules/locale/LocaleViewStep.h index eb8d64177..841aba97f 100644 --- a/src/modules/locale/LocaleViewStep.h +++ b/src/modules/locale/LocaleViewStep.h @@ -25,7 +25,7 @@ #include "utils/PluginFactory.h" #include "viewpages/ViewStep.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include #include diff --git a/src/modules/luksbootkeyfile/LuksBootKeyFileJob.h b/src/modules/luksbootkeyfile/LuksBootKeyFileJob.h index 2d4d6d319..de9b9c677 100644 --- a/src/modules/luksbootkeyfile/LuksBootKeyFileJob.h +++ b/src/modules/luksbootkeyfile/LuksBootKeyFileJob.h @@ -20,7 +20,7 @@ #define LUKSBOOTKEYFILEJOB_H #include "CppJob.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "utils/PluginFactory.h" #include diff --git a/src/modules/machineid/MachineIdJob.h b/src/modules/machineid/MachineIdJob.h index 5d44b2017..3e450accb 100644 --- a/src/modules/machineid/MachineIdJob.h +++ b/src/modules/machineid/MachineIdJob.h @@ -26,7 +26,7 @@ #include -#include +#include class PLUGINDLLEXPORT MachineIdJob : public Calamares::CppJob { diff --git a/src/modules/netinstall/NetInstallViewStep.h b/src/modules/netinstall/NetInstallViewStep.h index b07d3f96d..f26ba74ed 100644 --- a/src/modules/netinstall/NetInstallViewStep.h +++ b/src/modules/netinstall/NetInstallViewStep.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include diff --git a/src/modules/notesqml/NotesQmlViewStep.h b/src/modules/notesqml/NotesQmlViewStep.h index 445b34c81..5ffd4598e 100644 --- a/src/modules/notesqml/NotesQmlViewStep.h +++ b/src/modules/notesqml/NotesQmlViewStep.h @@ -20,7 +20,7 @@ #ifndef NOTESQMLVIEWSTEP_H #define NOTESQMLVIEWSTEP_H -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "locale/TranslatableConfiguration.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Variant.h" diff --git a/src/modules/oemid/OEMViewStep.h b/src/modules/oemid/OEMViewStep.h index d8722594a..57e2bba66 100644 --- a/src/modules/oemid/OEMViewStep.h +++ b/src/modules/oemid/OEMViewStep.h @@ -22,7 +22,7 @@ #include #include -#include +#include #include diff --git a/src/modules/packagechooser/PackageChooserViewStep.h b/src/modules/packagechooser/PackageChooserViewStep.h index 29e65ef82..9e9087971 100644 --- a/src/modules/packagechooser/PackageChooserViewStep.h +++ b/src/modules/packagechooser/PackageChooserViewStep.h @@ -19,7 +19,7 @@ #ifndef PACKAGECHOOSERVIEWSTEP_H #define PACKAGECHOOSERVIEWSTEP_H -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "locale/TranslatableConfiguration.h" #include "utils/PluginFactory.h" #include "viewpages/ViewStep.h" diff --git a/src/modules/partition/gui/PartitionViewStep.h b/src/modules/partition/gui/PartitionViewStep.h index 0a62b3aa3..f60dff1df 100644 --- a/src/modules/partition/gui/PartitionViewStep.h +++ b/src/modules/partition/gui/PartitionViewStep.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include "core/PartitionActions.h" diff --git a/src/modules/plasmalnf/PlasmaLnfViewStep.h b/src/modules/plasmalnf/PlasmaLnfViewStep.h index 01db17821..e99418549 100644 --- a/src/modules/plasmalnf/PlasmaLnfViewStep.h +++ b/src/modules/plasmalnf/PlasmaLnfViewStep.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/src/modules/preservefiles/PreserveFiles.h b/src/modules/preservefiles/PreserveFiles.h index ed2fe889c..587ac9bab 100644 --- a/src/modules/preservefiles/PreserveFiles.h +++ b/src/modules/preservefiles/PreserveFiles.h @@ -24,7 +24,7 @@ #include #include "CppJob.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "utils/PluginFactory.h" diff --git a/src/modules/shellprocess/ShellProcessJob.h b/src/modules/shellprocess/ShellProcessJob.h index d532aac99..708a43087 100644 --- a/src/modules/shellprocess/ShellProcessJob.h +++ b/src/modules/shellprocess/ShellProcessJob.h @@ -20,7 +20,7 @@ #define SHELLPROCESSJOB_H #include "CppJob.h" -#include "PluginDllMacro.h" +#include "DllMacro.h" #include "utils/CommandList.h" #include "utils/PluginFactory.h" diff --git a/src/modules/summary/SummaryViewStep.h b/src/modules/summary/SummaryViewStep.h index 88f177a4d..2c873e168 100644 --- a/src/modules/summary/SummaryViewStep.h +++ b/src/modules/summary/SummaryViewStep.h @@ -24,7 +24,7 @@ #include #include -#include +#include class SummaryPage; diff --git a/src/modules/tracking/TrackingViewStep.h b/src/modules/tracking/TrackingViewStep.h index dc952253a..df6497d68 100644 --- a/src/modules/tracking/TrackingViewStep.h +++ b/src/modules/tracking/TrackingViewStep.h @@ -21,7 +21,7 @@ #include "TrackingType.h" -#include +#include #include #include diff --git a/src/modules/users/UsersViewStep.h b/src/modules/users/UsersViewStep.h index 6fced76b9..74bdb84c4 100644 --- a/src/modules/users/UsersViewStep.h +++ b/src/modules/users/UsersViewStep.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include diff --git a/src/modules/webview/WebViewStep.h b/src/modules/webview/WebViewStep.h index c588318fa..9ee2dfac9 100644 --- a/src/modules/webview/WebViewStep.h +++ b/src/modules/webview/WebViewStep.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include diff --git a/src/modules/welcome/WelcomeViewStep.h b/src/modules/welcome/WelcomeViewStep.h index 4d8fa160f..217f827e9 100644 --- a/src/modules/welcome/WelcomeViewStep.h +++ b/src/modules/welcome/WelcomeViewStep.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include diff --git a/src/modules/welcomeq/WelcomeQmlViewStep.h b/src/modules/welcomeq/WelcomeQmlViewStep.h index 5486d8d31..468dd7621 100644 --- a/src/modules/welcomeq/WelcomeQmlViewStep.h +++ b/src/modules/welcomeq/WelcomeQmlViewStep.h @@ -25,7 +25,7 @@ #include "utils/PluginFactory.h" #include "viewpages/ViewStep.h" -#include +#include #include #include From 92260e7d0bbe5915f1c63f9036d6b7fd255bee22 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 11:43:20 +0100 Subject: [PATCH 30/78] [libcalamares] Document DllMacro.h and add STATICTEST - document the export macros - introduce a "static" that is switched off when re-building code for tests. --- src/libcalamares/DllMacro.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libcalamares/DllMacro.h b/src/libcalamares/DllMacro.h index 865d91d57..9bb789c94 100644 --- a/src/libcalamares/DllMacro.h +++ b/src/libcalamares/DllMacro.h @@ -21,6 +21,10 @@ #include +/* + * Mark symbols exported from Calamares libraries with DLLEXPORT. + * These are the public API of the libraries. + */ #ifndef DLLEXPORT #if defined( DLLEXPORT_PRO ) #define DLLEXPORT Q_DECL_EXPORT @@ -29,6 +33,11 @@ #endif #endif +/* + * Mark symbols exported from Calamares C++ plugins with PLUGINDLLEXPORT. + * These are the public API of the libraries (generally, the plugin + * entry point) + */ #ifndef PLUGINDLLEXPORT #if defined( PLUGINDLLEXPORT_PRO ) #define PLUGINDLLEXPORT Q_DECL_EXPORT @@ -37,4 +46,17 @@ #endif #endif +/* + * For functions that should be static in production but also need to + * be tested, use STATICTEST as linkage specifier. When built as part + * of a test, the function will be given normal linkage. + */ +#ifndef STATICTEST +#if defined( BUILD_AS_TEST ) +#define STATICTEST +#else +#define STATICTEST static +#endif +#endif + #endif From b42520b0ef9d05586a840fa5957daca2cb633521 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 11:51:56 +0100 Subject: [PATCH 31/78] [machineid] Apply new STATICTEST specifier, hide implementation details --- src/modules/machineid/Tests.cpp | 7 ++-- src/modules/machineid/Workers.cpp | 55 ++++++++++++++++--------------- src/modules/machineid/Workers.h | 3 -- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/modules/machineid/Tests.cpp b/src/modules/machineid/Tests.cpp index 53abd0482..874fac3cb 100644 --- a/src/modules/machineid/Tests.cpp +++ b/src/modules/machineid/Tests.cpp @@ -28,6 +28,9 @@ #include #include +// Internals of Workers.cpp +extern int getUrandomPoolSize(); + class MachineIdTests : public QObject { Q_OBJECT @@ -93,10 +96,10 @@ MachineIdTests::testPoolSize() { #ifdef Q_OS_FREEBSD // It hardly makes sense, but also the /proc entry is missing - QCOMPARE( MachineId::getUrandomPoolSize(), 512 ); + QCOMPARE( getUrandomPoolSize(), 512 ); #else // Based on a sample size of 1, Netrunner - QCOMPARE( MachineId::getUrandomPoolSize(), 4096 ); + QCOMPARE( getUrandomPoolSize(), 4096 ); #endif } diff --git a/src/modules/machineid/Workers.cpp b/src/modules/machineid/Workers.cpp index 39acdfbf2..76e466435 100644 --- a/src/modules/machineid/Workers.cpp +++ b/src/modules/machineid/Workers.cpp @@ -27,6 +27,34 @@ #include +/// @brief Returns a recommended size for the entropy pool (in bytes) +STATICTEST int +getUrandomPoolSize() +{ + QFile f( "/proc/sys/kernel/random/poolsize" ); + constexpr const int minimumPoolSize = 512; + int poolSize = minimumPoolSize; + + if ( f.exists() && f.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + QByteArray v = f.read( 16 ); + if ( v.length() > 2 ) + { + if ( v.endsWith( '\n' ) ) + { + v.chop( 1 ); + } + bool ok = false; + poolSize = v.toInt( &ok ); + if ( !ok ) + { + poolSize = minimumPoolSize; + } + } + } + return ( poolSize >= minimumPoolSize ) ? poolSize : minimumPoolSize; +} + namespace MachineId { @@ -59,33 +87,6 @@ copyFile( const QString& rootMountPoint, const QString& fileName ) return Calamares::JobResult::ok(); } -int -getUrandomPoolSize() -{ - QFile f( "/proc/sys/kernel/random/poolsize" ); - constexpr const int minimumPoolSize = 512; - int poolSize = minimumPoolSize; - - if ( f.exists() && f.open( QIODevice::ReadOnly | QIODevice::Text ) ) - { - QByteArray v = f.read( 16 ); - if ( v.length() > 2 ) - { - if ( v.endsWith( '\n' ) ) - { - v.chop( 1 ); - } - bool ok = false; - poolSize = v.toInt( &ok ); - if ( !ok ) - { - poolSize = minimumPoolSize; - } - } - } - return ( poolSize >= minimumPoolSize ) ? poolSize : minimumPoolSize; -} - Calamares::JobResult createNewEntropy( int poolSize, const QString& rootMountPoint, const QString& fileName ) { diff --git a/src/modules/machineid/Workers.h b/src/modules/machineid/Workers.h index 31561af1b..8cb8d74ff 100644 --- a/src/modules/machineid/Workers.h +++ b/src/modules/machineid/Workers.h @@ -48,9 +48,6 @@ enum class EntropyGeneration CopyFromHost }; -/// @brief Returns a recommended size for the entropy pool (in bytes) -int getUrandomPoolSize(); - /// @brief Creates a new entropy file @p fileName in the target system at @p rootMountPoint Calamares::JobResult createNewEntropy( int poolSize, const QString& rootMountPoint, const QString& fileName ); From 6bdc4a55de09c3b66fe43d661aecc0a774089602 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 12:02:53 +0100 Subject: [PATCH 32/78] CMake: new convenience module CalamaresAddTest --- CMakeLists.txt | 7 ++-- CMakeModules/CalamaresAddTest.cmake | 57 +++++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 CMakeModules/CalamaresAddTest.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bfe0fbab..479009faf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -549,10 +549,11 @@ install( "${PROJECT_BINARY_DIR}/CalamaresConfig.cmake" "${PROJECT_BINARY_DIR}/CalamaresConfigVersion.cmake" "${PROJECT_BINARY_DIR}/CalamaresUse.cmake" - "CMakeModules/CalamaresAddPlugin.cmake" - "CMakeModules/CalamaresAddModuleSubdirectory.cmake" - "CMakeModules/CalamaresAddLibrary.cmake" "CMakeModules/CalamaresAddBrandingSubdirectory.cmake" + "CMakeModules/CalamaresAddLibrary.cmake" + "CMakeModules/CalamaresAddModuleSubdirectory.cmake" + "CMakeModules/CalamaresAddPlugin.cmake" + "CMakeModules/CalamaresAddTest.cmake" "CMakeModules/CalamaresAddTranslations.cmake" "CMakeModules/CalamaresAutomoc.cmake" "CMakeModules/CMakeColors.cmake" diff --git a/CMakeModules/CalamaresAddTest.cmake b/CMakeModules/CalamaresAddTest.cmake new file mode 100644 index 000000000..2f8b1adb3 --- /dev/null +++ b/CMakeModules/CalamaresAddTest.cmake @@ -0,0 +1,57 @@ +# === This file is part of Calamares - === +# +# 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 . +# +# SPDX-License-Identifier: GPL-3.0+ +# License-Filename: LICENSE +# +### +# +# Support functions for building Calamares tests. +# This extends KDE's ECM tests with some custom patterns. +# +# calamares_add_test( +# +# [GUI] +# SOURCES +# ) + +include( CMakeParseArguments ) +include( CalamaresAutomoc ) + +function( calamares_add_test ) + # parse arguments (name needs to be saved before passing ARGN into the macro) + set( NAME ${ARGV0} ) + set( options GUI ) + set( multiValueArgs SOURCES ) + cmake_parse_arguments( TEST "${options}" "" "${multiValueArgs}" ${ARGN} ) + set( TEST_NAME ${NAME} ) + + if( ECM_FOUND AND BUILD_TESTING ) + ecm_add_test( + ${TEST_SOURCES} + TEST_NAME + ${TEST_NAME} + LINK_LIBRARIES + calamares + Qt5::Core + Qt5::Test + ) + calamares_automoc( ${TEST_NAME} ) + target_compile_definitions( ${TEST_NAME} PRIVATE -DBUILD_AS_TEST ) + if( TEST_GUI ) + target_link_libraries( ${TEST_NAME} PRIVATE calamaresui Qt5::Gui ) + endif() + endif() +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b73fecda0..1445b18f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,7 @@ include( CalamaresAddPlugin ) include( CalamaresAddModuleSubdirectory ) include( CalamaresAddLibrary ) include( CalamaresAddBrandingSubdirectory ) +include( CalamaresAddTest ) # library add_subdirectory( libcalamares ) From 637a57d534cb49f95ab313e5b6783a17ab7d108c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 12:04:18 +0100 Subject: [PATCH 33/78] [machineid] Change to calamares_add_test - The test-macro handles cases without ECM or testing transparently. - Adds compile defines for STATICTEST. --- src/modules/machineid/CMakeLists.txt | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/modules/machineid/CMakeLists.txt b/src/modules/machineid/CMakeLists.txt index a57d5163d..4a916334c 100644 --- a/src/modules/machineid/CMakeLists.txt +++ b/src/modules/machineid/CMakeLists.txt @@ -9,17 +9,10 @@ calamares_add_plugin( machineid SHARED_LIB ) -if ( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - MachineIdJob.cpp - Workers.cpp - TEST_NAME - machineidtest - LINK_LIBRARIES - calamares - Qt5::Core - Qt5::Test - ) - calamares_automoc( machineidtest ) -endif() +calamares_add_test( + machineidtest + SOURCES + Tests.cpp + MachineIdJob.cpp + Workers.cpp +) From 4495a4c739f3c3586b8f03425d6982aa5a0aac5d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 14:36:52 +0100 Subject: [PATCH 34/78] CMake: Allow extra libraries in calamares_add_test - Extra libraries specified via LIBRARIES part of CMake function - Convert all the other module tests --- CMakeModules/CalamaresAddTest.cmake | 5 ++-- src/modules/contextualprocess/CMakeLists.txt | 24 ++++++++------------ src/modules/fsresizer/CMakeLists.txt | 24 ++++++++------------ src/modules/hostinfo/CMakeLists.txt | 24 ++++++++------------ src/modules/initcpio/CMakeLists.txt | 24 ++++++++------------ src/modules/initramfs/CMakeLists.txt | 24 ++++++++------------ src/modules/locale/CMakeLists.txt | 18 +++++---------- src/modules/packagechooser/CMakeLists.txt | 24 ++++++++------------ src/modules/partition/tests/CMakeLists.txt | 18 ++++++--------- src/modules/shellprocess/CMakeLists.txt | 22 +++++++----------- src/modules/users/CMakeLists.txt | 22 +++++++----------- 11 files changed, 86 insertions(+), 143 deletions(-) diff --git a/CMakeModules/CalamaresAddTest.cmake b/CMakeModules/CalamaresAddTest.cmake index 2f8b1adb3..f1f6fdf3f 100644 --- a/CMakeModules/CalamaresAddTest.cmake +++ b/CMakeModules/CalamaresAddTest.cmake @@ -34,7 +34,7 @@ function( calamares_add_test ) # parse arguments (name needs to be saved before passing ARGN into the macro) set( NAME ${ARGV0} ) set( options GUI ) - set( multiValueArgs SOURCES ) + set( multiValueArgs SOURCES LIBRARIES ) cmake_parse_arguments( TEST "${options}" "" "${multiValueArgs}" ${ARGN} ) set( TEST_NAME ${NAME} ) @@ -45,13 +45,14 @@ function( calamares_add_test ) ${TEST_NAME} LINK_LIBRARIES calamares + ${TEST_LIBRARIES} Qt5::Core Qt5::Test ) calamares_automoc( ${TEST_NAME} ) target_compile_definitions( ${TEST_NAME} PRIVATE -DBUILD_AS_TEST ) if( TEST_GUI ) - target_link_libraries( ${TEST_NAME} PRIVATE calamaresui Qt5::Gui ) + target_link_libraries( ${TEST_NAME} calamaresui Qt5::Gui ) endif() endif() endfunction() diff --git a/src/modules/contextualprocess/CMakeLists.txt b/src/modules/contextualprocess/CMakeLists.txt index a7e9ed05b..05ed9a91b 100644 --- a/src/modules/contextualprocess/CMakeLists.txt +++ b/src/modules/contextualprocess/CMakeLists.txt @@ -8,18 +8,12 @@ calamares_add_plugin( contextualprocess SHARED_LIB ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - ContextualProcessJob.cpp # Builds it a second time - TEST_NAME - contextualprocesstest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - calamaresui - ${YAMLCPP_LIBRARY} - Qt5::Core - Qt5::Test - ) - calamares_automoc( contextualprocesstest ) -endif() +calamares_add_test( + contextualprocesstest + GUI # It's not + SOURCES + Tests.cpp + ContextualProcessJob.cpp # Builds it a second time + LIBRARIES + ${YAMLCPP_LIBRARY} +) diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index 3d82489b7..37890f66e 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -30,21 +30,15 @@ if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND SHARED_LIB ) - if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - TEST_NAME - fsresizertest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - calamares - calamares_job_fsresizer # From above - ${YAMLCPP_LIBRARY} - Qt5::Core - Qt5::Test - ) - set_target_properties( fsresizertest PROPERTIES AUTOMOC TRUE ) - target_include_directories( fsresizertest PRIVATE /usr/local/include ) + calamares_add_test( + fsresizertest + SOURCES + Tests.cpp + LIBRARIES + calamares_job_fsresizer # From above + ${YAMLCPP_LIBRARY} + ) + if( TARGET fsresizertest ) target_compile_definitions( fsresizertest PRIVATE ${_partition_defs} ) endif() else() diff --git a/src/modules/hostinfo/CMakeLists.txt b/src/modules/hostinfo/CMakeLists.txt index caf888625..125254ef9 100644 --- a/src/modules/hostinfo/CMakeLists.txt +++ b/src/modules/hostinfo/CMakeLists.txt @@ -32,18 +32,12 @@ if ( KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58 ) target_compile_definitions( calamares_job_hostinfo PRIVATE WITH_KOSRelease ) endif() -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - HostInfoJob.cpp # Builds it a second time - TEST_NAME - hostinfotest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - calamaresui - ${YAMLCPP_LIBRARY} - Qt5::Core - Qt5::Test - ) - calamares_automoc( hostinfotest ) -endif() +calamares_add_test( + hostinfotest + GUI # It's not + SOURCES + Tests.cpp + HostInfoJob.cpp + LIBRARIES + ${YAMLCPP_LIBRARY} +) diff --git a/src/modules/initcpio/CMakeLists.txt b/src/modules/initcpio/CMakeLists.txt index af217fb1a..fc0daea6f 100644 --- a/src/modules/initcpio/CMakeLists.txt +++ b/src/modules/initcpio/CMakeLists.txt @@ -8,18 +8,12 @@ calamares_add_plugin( initcpio SHARED_LIB ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - TEST_NAME - initcpiotest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - calamares - calamares_job_initcpio # From above - ${YAMLCPP_LIBRARY} - Qt5::Core - Qt5::Test - ) - calamares_automoc( initcpiotest ) -endif() +calamares_add_test( + initcpiotest + GUI # It's not + SOURCES + Tests.cpp + LIBRARIES + calamares_job_initcpio # From above + ${YAMLCPP_LIBRARY} +) diff --git a/src/modules/initramfs/CMakeLists.txt b/src/modules/initramfs/CMakeLists.txt index d7da12d55..7b59e140d 100644 --- a/src/modules/initramfs/CMakeLists.txt +++ b/src/modules/initramfs/CMakeLists.txt @@ -8,18 +8,12 @@ calamares_add_plugin( initramfs SHARED_LIB ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - TEST_NAME - initramfstest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - calamares - calamares_job_initramfs # From above - ${YAMLCPP_LIBRARY} - Qt5::Core - Qt5::Test - ) - calamares_automoc( initramfstest ) -endif() +calamares_add_test( + initramfstest + GUI # It's not + SOURCES + Tests.cpp + LIBRARIES + calamares_job_initramfs # From above + ${YAMLCPP_LIBRARY} +) diff --git a/src/modules/locale/CMakeLists.txt b/src/modules/locale/CMakeLists.txt index 768a67543..58788541e 100644 --- a/src/modules/locale/CMakeLists.txt +++ b/src/modules/locale/CMakeLists.txt @@ -31,15 +31,9 @@ calamares_add_plugin( locale SHARED_LIB ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - LocaleConfiguration.cpp - TEST_NAME - localetest - LINK_LIBRARIES - calamares - Qt5::Test - ) - calamares_automoc( localetest ) -endif() +calamares_add_test( + localetest + SOURCES + Tests.cpp + LocaleConfiguration.cpp +) diff --git a/src/modules/packagechooser/CMakeLists.txt b/src/modules/packagechooser/CMakeLists.txt index eeae655c9..d85eda8e2 100644 --- a/src/modules/packagechooser/CMakeLists.txt +++ b/src/modules/packagechooser/CMakeLists.txt @@ -53,18 +53,12 @@ calamares_add_plugin( packagechooser SHARED_LIB ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - TEST_NAME - packagechoosertest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - calamares_viewmodule_packagechooser - Qt5::Core - Qt5::Test - Qt5::Gui - ${_extra_libraries} - ) - calamares_automoc( packagechoosertest) -endif() +calamares_add_test( + packagechoosertest + GUI + SOURCES + Tests.cpp + LIBRARIES + calamares_viewmodule_packagechooser + ${_extra_libraries} +) diff --git a/src/modules/partition/tests/CMakeLists.txt b/src/modules/partition/tests/CMakeLists.txt index ac3968df9..fdba7e688 100644 --- a/src/modules/partition/tests/CMakeLists.txt +++ b/src/modules/partition/tests/CMakeLists.txt @@ -21,16 +21,12 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( ${partitionjobtests_SRCS} - TEST_NAME partitionjobtests - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - kpmcore - Qt5::Core - Qt5::Test - ) - - set_target_properties( partitionjobtests PROPERTIES AUTOMOC TRUE ) +calamares_add_test( + partitionjobtests + SOURCES ${partitionjobtests_SRCS} + LIBRARIES + kpmcore +) +if( TARGET partitionjobtests ) target_compile_definitions( partitionjobtests PRIVATE ${_partition_defs} ) endif() diff --git a/src/modules/shellprocess/CMakeLists.txt b/src/modules/shellprocess/CMakeLists.txt index 166dff17d..3899ef642 100644 --- a/src/modules/shellprocess/CMakeLists.txt +++ b/src/modules/shellprocess/CMakeLists.txt @@ -8,17 +8,11 @@ calamares_add_plugin( shellprocess SHARED_LIB ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - Tests.cpp - TEST_NAME - shellprocesstest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - calamaresui - ${YAMLCPP_LIBRARY} - Qt5::Core - Qt5::Test - ) - calamares_automoc( shellprocesstest ) -endif() +calamares_add_test( + shellprocesstest + GUI # It's not + SOURCES + Tests.cpp + LIBRARIES + ${YAMLCPP_LIBRARY} +) diff --git a/src/modules/users/CMakeLists.txt b/src/modules/users/CMakeLists.txt index d0e7b6d9d..75d2233c4 100644 --- a/src/modules/users/CMakeLists.txt +++ b/src/modules/users/CMakeLists.txt @@ -39,17 +39,11 @@ calamares_add_plugin( users SHARED_LIB ) -if( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - PasswordTests.cpp - SetPasswordJob.cpp - TEST_NAME - passwordtest - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - Qt5::Core - Qt5::Test - ${CRYPT_LIBRARIES} - ) - calamares_automoc( passwordtest ) -endif() +calamares_add_test( + passwordtest + SOURCES + PasswordTests.cpp + SetPasswordJob.cpp + LIBRARIES + ${CRYPT_LIBRARIES} +) From 6f996d8eedb80d9d53de14595f26f2119ef3bdcb Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 14:55:12 +0100 Subject: [PATCH 35/78] CMake: give yamlcpp a proper imported target - This makes linking easier, - Adds the right includes (needed on FreeBSD), - Lets us drop silly GUI setting for non-GUI tests (I think this was a side-effect of compiling on FreeBSD, where UI would pull in /usr/local/include). --- CMakeModules/FindYAMLCPP.cmake | 17 ++++++++++++++--- src/modules/contextualprocess/CMakeLists.txt | 3 +-- src/modules/fsresizer/CMakeLists.txt | 2 +- src/modules/hostinfo/CMakeLists.txt | 3 +-- src/modules/initcpio/CMakeLists.txt | 3 +-- src/modules/initramfs/CMakeLists.txt | 3 +-- src/modules/locale/CMakeLists.txt | 2 +- src/modules/shellprocess/CMakeLists.txt | 3 +-- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CMakeModules/FindYAMLCPP.cmake b/CMakeModules/FindYAMLCPP.cmake index 1ec9798d5..395c794bb 100644 --- a/CMakeModules/FindYAMLCPP.cmake +++ b/CMakeModules/FindYAMLCPP.cmake @@ -1,9 +1,11 @@ # Locate yaml-cpp # # This module defines -# YAMLCPP_FOUND, if false, do not try to link to yaml-cpp -# YAMLCPP_LIBRARY, where to find yaml-cpp -# YAMLCPP_INCLUDE_DIR, where to find yaml.h +# YAMLCPP_FOUND, if false, do not try to link to yaml-cpp +# YAMLCPP_LIBRARY, where to find yaml-cpp +# YAMLCPP_INCLUDE_DIR, where to find yaml.h +# There is also one IMPORTED library target, +# yamlcpp # # By default, the dynamic libraries of yaml-cpp will be found. To find the static ones instead, # you must set the YAMLCPP_STATIC_LIBRARY variable to TRUE before calling find_package(YamlCpp ...). @@ -48,3 +50,12 @@ find_library(YAMLCPP_LIBRARY include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(YAMLCPP DEFAULT_MSG YAMLCPP_INCLUDE_DIR YAMLCPP_LIBRARY) mark_as_advanced(YAMLCPP_INCLUDE_DIR YAMLCPP_LIBRARY) + +# Add an imported target +if( YAMLCPP_LIBRARY ) + add_library( yamlcpp UNKNOWN IMPORTED ) + set_property( TARGET yamlcpp PROPERTY IMPORTED_LOCATION ${YAMLCPP_LIBRARY} ) + if ( YAMLCPP_INCLUDE_DIR ) + set_property( TARGET yamlcpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${YAMLCPP_INCLUDE_DIR} ) + endif() +endif() diff --git a/src/modules/contextualprocess/CMakeLists.txt b/src/modules/contextualprocess/CMakeLists.txt index 05ed9a91b..2df4cfe37 100644 --- a/src/modules/contextualprocess/CMakeLists.txt +++ b/src/modules/contextualprocess/CMakeLists.txt @@ -10,10 +10,9 @@ calamares_add_plugin( contextualprocess calamares_add_test( contextualprocesstest - GUI # It's not SOURCES Tests.cpp ContextualProcessJob.cpp # Builds it a second time LIBRARIES - ${YAMLCPP_LIBRARY} + yamlcpp ) diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index 37890f66e..01f673eb8 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -36,7 +36,7 @@ if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND Tests.cpp LIBRARIES calamares_job_fsresizer # From above - ${YAMLCPP_LIBRARY} + yamlcpp ) if( TARGET fsresizertest ) target_compile_definitions( fsresizertest PRIVATE ${_partition_defs} ) diff --git a/src/modules/hostinfo/CMakeLists.txt b/src/modules/hostinfo/CMakeLists.txt index 125254ef9..3d6e0973f 100644 --- a/src/modules/hostinfo/CMakeLists.txt +++ b/src/modules/hostinfo/CMakeLists.txt @@ -34,10 +34,9 @@ endif() calamares_add_test( hostinfotest - GUI # It's not SOURCES Tests.cpp HostInfoJob.cpp LIBRARIES - ${YAMLCPP_LIBRARY} + yamlcpp ) diff --git a/src/modules/initcpio/CMakeLists.txt b/src/modules/initcpio/CMakeLists.txt index fc0daea6f..5140c97e0 100644 --- a/src/modules/initcpio/CMakeLists.txt +++ b/src/modules/initcpio/CMakeLists.txt @@ -10,10 +10,9 @@ calamares_add_plugin( initcpio calamares_add_test( initcpiotest - GUI # It's not SOURCES Tests.cpp LIBRARIES calamares_job_initcpio # From above - ${YAMLCPP_LIBRARY} + yamlcpp ) diff --git a/src/modules/initramfs/CMakeLists.txt b/src/modules/initramfs/CMakeLists.txt index 7b59e140d..b3287c896 100644 --- a/src/modules/initramfs/CMakeLists.txt +++ b/src/modules/initramfs/CMakeLists.txt @@ -10,10 +10,9 @@ calamares_add_plugin( initramfs calamares_add_test( initramfstest - GUI # It's not SOURCES Tests.cpp LIBRARIES calamares_job_initramfs # From above - ${YAMLCPP_LIBRARY} + yamlcpp ) diff --git a/src/modules/locale/CMakeLists.txt b/src/modules/locale/CMakeLists.txt index 58788541e..cae2ea41c 100644 --- a/src/modules/locale/CMakeLists.txt +++ b/src/modules/locale/CMakeLists.txt @@ -27,7 +27,7 @@ calamares_add_plugin( locale calamaresui Qt5::Network ${geoip_libs} - ${YAMLCPP_LIBRARY} + yamlcpp SHARED_LIB ) diff --git a/src/modules/shellprocess/CMakeLists.txt b/src/modules/shellprocess/CMakeLists.txt index 3899ef642..ec1cf0bcf 100644 --- a/src/modules/shellprocess/CMakeLists.txt +++ b/src/modules/shellprocess/CMakeLists.txt @@ -10,9 +10,8 @@ calamares_add_plugin( shellprocess calamares_add_test( shellprocesstest - GUI # It's not SOURCES Tests.cpp LIBRARIES - ${YAMLCPP_LIBRARY} + yamlcpp ) From 51e135cfbd3a24ec5b23b18ed99f195911455143 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 15:01:05 +0100 Subject: [PATCH 36/78] CMake: chase introduction of IMPORTED yamlcpp --- src/libcalamares/CMakeLists.txt | 6 ++---- src/modules/CMakeLists.txt | 2 +- src/modules/netinstall/CMakeLists.txt | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index cad7e7a6e..ae927eda1 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -74,7 +74,6 @@ mark_thirdparty_code( ${kdsagSources} ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} - ${YAMLCPP_INCLUDE_DIR} ) ### OPTIONAL Python support @@ -126,7 +125,7 @@ target_link_libraries( calamares LINK_PRIVATE ${OPTIONAL_PRIVATE_LIBRARIES} LINK_PUBLIC - ${YAMLCPP_LIBRARY} + yamlcpp Qt5::Core KF5::CoreAddons ${OPTIONAL_PUBLIC_LIBRARIES} @@ -191,7 +190,6 @@ if ( ECM_FOUND AND BUILD_TESTING ) LINK_LIBRARIES calamares Qt5::Test - ${YAMLCPP_LIBRARY} ) calamares_automoc( geoiptest ) @@ -238,6 +236,6 @@ endif() if( BUILD_TESTING ) add_executable( test_geoip geoip/test_geoip.cpp ${geoip_src} ) - target_link_libraries( test_geoip calamares Qt5::Network ${YAMLCPP_LIBRARY} ) + target_link_libraries( test_geoip calamares Qt5::Network yamlcpp ) calamares_automoc( test_geoip ) endif() diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 9e9621106..b72b755d3 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -12,7 +12,7 @@ include_directories( if( BUILD_TESTING ) add_executable( test_conf test_conf.cpp ) - target_link_libraries( test_conf ${YAMLCPP_LIBRARY} Qt5::Core ) + target_link_libraries( test_conf yamlcpp Qt5::Core ) target_include_directories( test_conf PUBLIC ${YAMLCPP_INCLUDE_DIR} ) endif() diff --git a/src/modules/netinstall/CMakeLists.txt b/src/modules/netinstall/CMakeLists.txt index 67f805734..c5eddd32b 100644 --- a/src/modules/netinstall/CMakeLists.txt +++ b/src/modules/netinstall/CMakeLists.txt @@ -1,5 +1,3 @@ -include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ) - calamares_add_plugin( netinstall TYPE viewmodule EXPORT_MACRO PLUGINDLLEXPORT_PRO @@ -15,6 +13,6 @@ calamares_add_plugin( netinstall LINK_PRIVATE_LIBRARIES calamaresui Qt5::Network - ${YAMLCPP_LIBRARY} + yamlcpp SHARED_LIB ) From 6719a41aef0af3776a4d0a55443d6c4131bbb39f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 15:05:00 +0100 Subject: [PATCH 37/78] [libcalamares] Switch tests to calamares_add_test() --- src/libcalamares/CMakeLists.txt | 105 +++++++++++--------------------- 1 file changed, 36 insertions(+), 69 deletions(-) diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index ae927eda1..803c46870 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -158,81 +158,48 @@ install( FILES ${utilsHeaders} DESTINATION include/libcalam ### TESTING # # -if ( ECM_FOUND AND BUILD_TESTING ) - ecm_add_test( - utils/Tests.cpp - TEST_NAME - libcalamarestest - LINK_LIBRARIES - calamares - Qt5::Core - Qt5::Test - ) - calamares_automoc( libcalamarestest ) +calamares_add_test( + libcalamarestest + SOURCES + utils/Tests.cpp +) - ecm_add_test( - utils/TestPaths.cpp - TEST_NAME - libcalamarestestpaths - LINK_LIBRARIES - calamares - Qt5::Core - Qt5::Test - ) - calamares_automoc( libcalamarestestpaths ) +calamares_add_test( + libcalamarestestpaths + SOURCES + utils/TestPaths.cpp +) +calamares_add_test( + geoiptest + SOURCES + geoip/GeoIPTests.cpp + ${geoip_src} +) - ecm_add_test( - geoip/GeoIPTests.cpp - ${geoip_src} - TEST_NAME - geoiptest - LINK_LIBRARIES - calamares - Qt5::Test - ) - calamares_automoc( geoiptest ) +calamares_add_test( + libcalamarespartitiontest + SOURCES + partition/Tests.cpp +) - ecm_add_test( - partition/Tests.cpp - TEST_NAME - libcalamarespartitiontest - LINK_LIBRARIES - calamares - Qt5::Test - ) - calamares_automoc( libcalamarespartitiontest ) +calamares_add_test( + libcalamareslocaletest + SOURCES + locale/Tests.cpp +) - ecm_add_test( - locale/Tests.cpp - TEST_NAME - libcalamareslocaletest - LINK_LIBRARIES - calamares - Qt5::Test - ) - calamares_automoc( libcalamareslocaletest ) +calamares_add_test( + libcalamaresnetworktest + SOURCES + network/Tests.cpp +) - ecm_add_test( - network/Tests.cpp - TEST_NAME - libcalamaresnetworktest - LINK_LIBRARIES - calamares - Qt5::Test - ) - calamares_automoc( libcalamaresnetworktest ) - - ecm_add_test( - modulesystem/Tests.cpp - TEST_NAME - libcalamaresmodulesystemtest - LINK_LIBRARIES - calamares - Qt5::Test - ) - calamares_automoc( libcalamaresmodulesystemtest ) -endif() +calamares_add_test( + libcalamaresmodulesystemtest + SOURCES + modulesystem/Tests.cpp +) if( BUILD_TESTING ) add_executable( test_geoip geoip/test_geoip.cpp ${geoip_src} ) From ef4bb5e13bca0c1bf276f20086466d06a130dd1a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 15:24:44 +0100 Subject: [PATCH 38/78] [users] Make SetHostName job actions configurable --- src/modules/users/SetHostNameJob.cpp | 27 ++++++++++++++++++++------- src/modules/users/SetHostNameJob.h | 14 +++++++++++++- src/modules/users/UsersPage.cpp | 3 ++- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index de98854ec..7c81329a7 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -31,9 +31,10 @@ #include #include -SetHostNameJob::SetHostNameJob( const QString& hostname ) +SetHostNameJob::SetHostNameJob( const QString& hostname, Actions a ) : Calamares::Job() , m_hostname( hostname ) + , m_actions( a ) { } @@ -127,16 +128,28 @@ SetHostNameJob::exec() return Calamares::JobResult::error( tr( "Internal Error" ) ); } - if ( !setFileHostname( m_hostname ) ) + if ( m_actions & Action::EtcHostname ) { - cError() << "Can't write to hostname file"; - return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); + if ( !setFileHostname( m_hostname ) ) + { + cError() << "Can't write to hostname file"; + return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); + } } - if ( !writeFileEtcHosts( m_hostname ) ) + if ( m_actions & Action::EtcHosts ) { - cError() << "Can't write to hosts file"; - return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); + if ( !writeFileEtcHosts( m_hostname ) ) + { + cError() << "Can't write to hosts file"; + return Calamares::JobResult::error( tr( "Cannot write hostname to target system" ) ); + } + } + + if ( m_actions & Action::SystemdHostname ) + { + // Does its own logging + setSystemdHostname( m_hostname ); } return Calamares::JobResult::ok(); diff --git a/src/modules/users/SetHostNameJob.h b/src/modules/users/SetHostNameJob.h index ca2481dd4..bc1d1d8ac 100644 --- a/src/modules/users/SetHostNameJob.h +++ b/src/modules/users/SetHostNameJob.h @@ -26,7 +26,17 @@ class SetHostNameJob : public Calamares::Job { Q_OBJECT public: - SetHostNameJob( const QString& hostname ); + enum Action + { + None = 0x0, + EtcHostname = 0x1, // Write to /etc/hostname directly + SystemdHostname = 0x2, // Set via hostnamed(1) + EtcHosts = 0x4 // Write /etc/hosts (127.0.1.1 is this host) + }; + Q_DECLARE_FLAGS( Actions, Action ) + + + SetHostNameJob( const QString& hostname, Actions a ); QString prettyName() const override; QString prettyDescription() const override; QString prettyStatusMessage() const override; @@ -34,7 +44,9 @@ public: private: const QString m_hostname; + const Actions m_actions; }; +Q_DECLARE_OPERATORS_FOR_FLAGS( SetHostNameJob::Actions ) #endif // SETHOSTNAMEJOB_CPP_H diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index c5c6ef8d4..f4e88b629 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -209,7 +209,8 @@ UsersPage::createJobs( const QStringList& defaultGroupsList ) list.append( Calamares::job_ptr( j ) ); } - j = new SetHostNameJob( ui->textBoxHostname->text() ); + j = new SetHostNameJob( ui->textBoxHostname->text(), + SetHostNameJob::Action::EtcHostname | SetHostNameJob::Action::EtcHosts ); list.append( Calamares::job_ptr( j ) ); gs->insert( "hostname", ui->textBoxHostname->text() ); From 2471e74aab02792958f4c4d451aa05f40d59ebd3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 15:43:53 +0100 Subject: [PATCH 39/78] [users] Provide some accessors to the UI-page data --- src/modules/users/UsersPage.cpp | 51 ++++++++++++++++++++++----------- src/modules/users/UsersPage.h | 7 +++++ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index f4e88b629..f2b9187af 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -166,6 +166,37 @@ UsersPage::isReady() return readyFields && m_readyRootPassword; } +QString +UsersPage::getHostname() const +{ + return ui->textBoxHostname->text(); +} + +QString +UsersPage::getRootPassword() const +{ + if ( m_writeRootPassword ) + { + if ( ui->checkBoxReusePassword->isChecked() ) + { + return ui->textBoxUserPassword->text(); + } + else + { + return ui->textBoxRootPassword->text(); + } + } + else + { + return QString(); + } +} + +QPair< QString, QString > +UsersPage::getUserPassword() const +{ + return QPair< QString, QString >( ui->textBoxUsername->text(), ui->textBoxUserPassword->text() ); +} QList< Calamares::job_ptr > UsersPage::createJobs( const QStringList& defaultGroupsList ) @@ -192,25 +223,11 @@ UsersPage::createJobs( const QStringList& defaultGroupsList ) if ( m_writeRootPassword ) { gs->insert( "reuseRootPassword", ui->checkBoxReusePassword->isChecked() ); - if ( ui->checkBoxReusePassword->isChecked() ) - { - j = new SetPasswordJob( "root", ui->textBoxUserPassword->text() ); - } - else - { - j = new SetPasswordJob( "root", ui->textBoxRootPassword->text() ); - } - list.append( Calamares::job_ptr( j ) ); - } - else - { - j = new SetPasswordJob( "root", - "" ); //explicitly disable root password - list.append( Calamares::job_ptr( j ) ); } + j = new SetPasswordJob( "root", getRootPassword() ); + list.append( Calamares::job_ptr( j ) ); - j = new SetHostNameJob( ui->textBoxHostname->text(), - SetHostNameJob::Action::EtcHostname | SetHostNameJob::Action::EtcHosts ); + j = new SetHostNameJob( getHostname(), SetHostNameJob::Action::EtcHostname | SetHostNameJob::Action::EtcHosts ); list.append( Calamares::job_ptr( j ) ); gs->insert( "hostname", ui->textBoxHostname->text() ); diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index c6bf87ecf..3382e9335 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -63,6 +63,13 @@ public: */ void addPasswordCheck( const QString& key, const QVariant& value ); + ///@brief Hostname as entered / auto-filled + QString getHostname() const; + ///@brief Root password, depends on settings, may be empty + QString getRootPassword() const; + ///@brief User name and password + QPair< QString, QString > getUserPassword() const; + protected slots: void onFullNameTextEdited( const QString& ); void fillSuggestions(); From dbba0c9b039b1c06895411b09b4cf97c75be6b47 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 15:56:41 +0100 Subject: [PATCH 40/78] [users] Move Job creation from the widget to the ViewStep - Having the widget do creation ties the step heavily to that UI; start moving towards a state where we have a Config object (not here yet; it still queries the UI part) that moves data around between UI and ViewStep. --- src/modules/users/UsersPage.cpp | 9 --------- src/modules/users/UsersViewStep.cpp | 17 +++++++++++++++-- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/modules/users/UsersPage.cpp b/src/modules/users/UsersPage.cpp index f2b9187af..21f472a40 100644 --- a/src/modules/users/UsersPage.cpp +++ b/src/modules/users/UsersPage.cpp @@ -217,19 +217,10 @@ UsersPage::createJobs( const QStringList& defaultGroupsList ) defaultGroupsList ); list.append( Calamares::job_ptr( j ) ); - j = new SetPasswordJob( ui->textBoxUsername->text(), ui->textBoxUserPassword->text() ); - list.append( Calamares::job_ptr( j ) ); - if ( m_writeRootPassword ) { gs->insert( "reuseRootPassword", ui->checkBoxReusePassword->isChecked() ); } - j = new SetPasswordJob( "root", getRootPassword() ); - list.append( Calamares::job_ptr( j ) ); - - j = new SetHostNameJob( getHostname(), SetHostNameJob::Action::EtcHostname | SetHostNameJob::Action::EtcHosts ); - list.append( Calamares::job_ptr( j ) ); - gs->insert( "hostname", ui->textBoxHostname->text() ); if ( ui->checkBoxAutoLogin->isChecked() ) { diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 0f42d1476..363328495 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -20,9 +20,10 @@ #include "UsersViewStep.h" +#include "SetHostNameJob.h" +#include "SetPasswordJob.h" #include "UsersPage.h" -// #include "utils/CalamaresUtils.h" #include "utils/Logger.h" #include "utils/Variant.h" @@ -109,8 +110,20 @@ void UsersViewStep::onLeave() { m_jobs.clear(); - m_jobs.append( m_widget->createJobs( m_defaultGroups ) ); + + Calamares::Job* j; + + auto userPW = m_widget->getUserPassword(); + j = new SetPasswordJob( userPW.first, userPW.second ); + m_jobs.append( Calamares::job_ptr( j ) ); + + j = new SetPasswordJob( "root", m_widget->getRootPassword() ); + m_jobs.append( Calamares::job_ptr( j ) ); + + j = new SetHostNameJob( m_widget->getHostname(), + SetHostNameJob::Action::EtcHostname | SetHostNameJob::Action::EtcHosts ); + m_jobs.append( Calamares::job_ptr( j ) ); } From 33b3321698e8afea17b6fcb061a9a46f415bf474 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 16:05:55 +0100 Subject: [PATCH 41/78] [users] Simplify reading configuration --- src/modules/users/UsersViewStep.cpp | 30 +++++++++-------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 363328495..37b4ed51e 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -130,6 +130,8 @@ UsersViewStep::onLeave() void UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { + using CalamaresUtils::getBool; + if ( configurationMap.contains( "defaultGroups" ) && configurationMap.value( "defaultGroups" ).type() == QVariant::List ) { @@ -155,25 +157,12 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) configurationMap.value( "sudoersGroup" ).toString() ); } - if ( configurationMap.contains( "setRootPassword" ) - && configurationMap.value( "setRootPassword" ).type() == QVariant::Bool ) - { - Calamares::JobQueue::instance()->globalStorage()->insert( - "setRootPassword", configurationMap.value( "setRootPassword" ).toBool() ); - m_widget->setWriteRootPassword( configurationMap.value( "setRootPassword" ).toBool() ); - } + bool setRootPassword = getBool( configurationMap, "setRootPassword", true ); + Calamares::JobQueue::instance()->globalStorage()->insert( "setRootPassword", setRootPassword ); - if ( configurationMap.contains( "doAutologin" ) - && configurationMap.value( "doAutologin" ).type() == QVariant::Bool ) - { - m_widget->setAutologinDefault( configurationMap.value( "doAutologin" ).toBool() ); - } - - if ( configurationMap.contains( "doReusePassword" ) - && configurationMap.value( "doReusePassword" ).type() == QVariant::Bool ) - { - m_widget->setReusePasswordDefault( configurationMap.value( "doReusePassword" ).toBool() ); - } + m_widget->setWriteRootPassword( setRootPassword ); + m_widget->setAutologinDefault( getBool( configurationMap, "doAutologin", false ) ); + m_widget->setReusePasswordDefault( getBool( configurationMap, "doReusePassword", false ) ); if ( configurationMap.contains( "passwordRequirements" ) && configurationMap.value( "passwordRequirements" ).type() == QVariant::Map ) @@ -186,9 +175,8 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } } - m_widget->setPasswordCheckboxVisible( CalamaresUtils::getBool( configurationMap, "allowWeakPasswords", false ) ); - m_widget->setValidatePasswordDefault( - !CalamaresUtils::getBool( configurationMap, "allowWeakPasswordsDefault", false ) ); + m_widget->setPasswordCheckboxVisible( getBool( configurationMap, "allowWeakPasswords", false ) ); + m_widget->setValidatePasswordDefault( !getBool( configurationMap, "allowWeakPasswordsDefault", false ) ); QString shell( QLatin1String( "/bin/bash" ) ); // as if it's not set at all if ( configurationMap.contains( "userShell" ) ) From 61d096c9ec3c7137c2eae185abe67d0e9f778da2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 16:27:53 +0100 Subject: [PATCH 42/78] [users] Prep-work for configurable actions - tidy include style - add setting to UsersViewStep for hostname action --- src/modules/users/UsersViewStep.cpp | 20 ++++++++++++++++++++ src/modules/users/UsersViewStep.h | 13 +++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 37b4ed51e..695ba109f 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -25,6 +25,7 @@ #include "UsersPage.h" #include "utils/Logger.h" +#include "utils/NamedEnum.h" #include "utils/Variant.h" #include "GlobalStorage.h" @@ -32,9 +33,28 @@ CALAMARES_PLUGIN_FACTORY_DEFINITION( UsersViewStepFactory, registerPlugin< UsersViewStep >(); ) +static const NamedEnumTable< SetHostNameJob::Action >& +hostnameActions() +{ + using Action = SetHostNameJob::Action; + + // *INDENT-OFF* + // clang-format off + static const NamedEnumTable< Action > names { + { QStringLiteral( "none" ), Action::None }, + { QStringLiteral( "etcfile" ), Action::EtcHostname }, + { QStringLiteral( "hostnamed" ), Action::SystemdHostname } + }; + // clang-format on + // *INDENT-ON* + + return names; +} + UsersViewStep::UsersViewStep( QObject* parent ) : Calamares::ViewStep( parent ) , m_widget( new UsersPage() ) + , m_actions( SetHostNameJob::Action::None ) { emit nextStatusChanged( true ); connect( m_widget, &UsersPage::checkReady, this, &UsersViewStep::nextStatusChanged ); diff --git a/src/modules/users/UsersViewStep.h b/src/modules/users/UsersViewStep.h index 6fced76b9..194fcecb4 100644 --- a/src/modules/users/UsersViewStep.h +++ b/src/modules/users/UsersViewStep.h @@ -20,13 +20,13 @@ #ifndef USERSPAGEPLUGIN_H #define USERSPAGEPLUGIN_H +#include "SetHostNameJob.h" + +#include "PluginDllMacro.h" +#include "utils/PluginFactory.h" +#include "viewpages/ViewStep.h" + #include - -#include -#include - -#include - #include class UsersPage; @@ -61,6 +61,7 @@ private: QList< Calamares::job_ptr > m_jobs; QStringList m_defaultGroups; + SetHostNameJob::Actions m_actions; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( UsersViewStepFactory ) From e74831fcb460e023f7bcf48f16c1ac6c88a1e63e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 16:40:09 +0100 Subject: [PATCH 43/78] [users] Add .conf entries for hostname settings - Set hostname not-at-all, or via one of two mechanisms - Write /etc/hosts or not --- src/modules/users/UsersViewStep.cpp | 20 +++++++++++++++-- src/modules/users/users.conf | 34 ++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 695ba109f..759fdb3e1 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -141,8 +141,7 @@ UsersViewStep::onLeave() j = new SetPasswordJob( "root", m_widget->getRootPassword() ); m_jobs.append( Calamares::job_ptr( j ) ); - j = new SetHostNameJob( m_widget->getHostname(), - SetHostNameJob::Action::EtcHostname | SetHostNameJob::Action::EtcHosts ); + j = new SetHostNameJob( m_widget->getHostname(), m_actions ); m_jobs.append( Calamares::job_ptr( j ) ); } @@ -206,4 +205,21 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) // Now it might be explicitly set to empty, which is ok Calamares::JobQueue::instance()->globalStorage()->insert( "userShell", shell ); + + using Action = SetHostNameJob::Action; + + QString hostnameActionString = CalamaresUtils::getString( configurationMap, "setHostname" ); + if ( hostnameActionString.isEmpty() ) + { + hostnameActionString = QStringLiteral( "EtcFile" ); + } + bool ok = false; + auto hostnameAction = hostnameActions().find( hostnameActionString, ok ); + if ( !ok ) + { + hostnameAction = Action::EtcHostname; + } + + Action hostsfileAction = getBool( configurationMap, "writeHostsFile", true ) ? Action::EtcHosts : Action::None; + m_actions = hostsfileAction | hostnameAction; } diff --git a/src/modules/users/users.conf b/src/modules/users/users.conf index 00747195c..1c928fd3a 100644 --- a/src/modules/users/users.conf +++ b/src/modules/users/users.conf @@ -28,13 +28,13 @@ defaultGroups: # Disable when your Distribution does not require such a group. autologinGroup: autologin # You can control the initial state for the 'autologin checkbox' here. -# Possible values are: -# - true to check or +# Possible values are: +# - true to check or # - false to uncheck # These set the **initial** state of the checkbox. doAutologin: true -# When *sudoersGroup* is set to a non-empty string, Calamares creates a +# When *sudoersGroup* is set to a non-empty string, Calamares creates a # sudoers file for the user. This file is located at: # `/etc/sudoers.d/10-installer` # Remember to add the (value of) *sudoersGroup* to *defaultGroups*. @@ -48,8 +48,8 @@ sudoersGroup: wheel # Setting this to false , causes the root account to be disabled. setRootPassword: true # You can control the initial state for the 'reuse password for root' -# checkbox here. Possible values are: -# - true to check or +# checkbox here. Possible values are: +# - true to check or # - false to uncheck # # When checked, the user password is used for the root account too. @@ -96,18 +96,18 @@ passwordRequirements: libpwquality: - minlen=0 - minclass=0 - + # You can control the visibility of the 'strong passwords' checkbox here. -# Possible values are: -# - true to show or +# Possible values are: +# - true to show or # - false to hide (default) # the checkbox. This checkbox allows the user to choose to disable # password-strength-checks. By default the box is **hidden**, so # that you have to pick a password that satisfies the checks. allowWeakPasswords: false # You can control the initial state for the 'strong passwords' checkbox here. -# Possible values are: -# - true to uncheck or +# Possible values are: +# - true to uncheck or # - false to check (default) # the checkbox by default. Since the box is labeled to enforce strong # passwords, in order to **allow** weak ones by default, the box needs @@ -122,3 +122,17 @@ allowWeakPasswordsDefault: false # - set, non-empty, use that path as shell. No validation is done # that the shell actually exists or is executable. # userShell: /bin/bash + +# Hostname setting +# +# The user can enter a hostname; this is configured into the system +# in some way; pick one of: +# - *None*, to not set the hostname at all +# - *EtcFile*, to write to `/etc/hostname` directly +# - *Hostnamed*, to use systemd hostnamed(1) over DBus +# The default is *EtcFile*. +setHostname: EtcFile + +# Should /etc/hosts be written with a hostname for this machine +# (also adds localhost and some ipv6 standard entries). +writeHostsFile: true From 49eb8212e3144c3efb3d02bf904f35aead6363a8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 16:46:06 +0100 Subject: [PATCH 44/78] [users] Imporove enum-naming --- src/modules/users/SetHostNameJob.cpp | 2 +- src/modules/users/SetHostNameJob.h | 2 +- src/modules/users/UsersViewStep.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index 7c81329a7..62ef8cc1b 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -137,7 +137,7 @@ SetHostNameJob::exec() } } - if ( m_actions & Action::EtcHosts ) + if ( m_actions & Action::WriteEtcHosts ) { if ( !writeFileEtcHosts( m_hostname ) ) { diff --git a/src/modules/users/SetHostNameJob.h b/src/modules/users/SetHostNameJob.h index bc1d1d8ac..e4c2f2510 100644 --- a/src/modules/users/SetHostNameJob.h +++ b/src/modules/users/SetHostNameJob.h @@ -31,7 +31,7 @@ public: None = 0x0, EtcHostname = 0x1, // Write to /etc/hostname directly SystemdHostname = 0x2, // Set via hostnamed(1) - EtcHosts = 0x4 // Write /etc/hosts (127.0.1.1 is this host) + WriteEtcHosts = 0x4 // Write /etc/hosts (127.0.1.1 is this host) }; Q_DECLARE_FLAGS( Actions, Action ) diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 759fdb3e1..fe633b1c2 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -220,6 +220,6 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) hostnameAction = Action::EtcHostname; } - Action hostsfileAction = getBool( configurationMap, "writeHostsFile", true ) ? Action::EtcHosts : Action::None; + Action hostsfileAction = getBool( configurationMap, "writeHostsFile", true ) ? Action::WriteEtcHosts : Action::None; m_actions = hostsfileAction | hostnameAction; } From 94f5b13db0abda48d48a640a0f6e0e4801d14453 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 16:52:45 +0100 Subject: [PATCH 45/78] [libcalamaresui] Restore previous DLLEXPORT names - Different libraries should have different EXPORTs, so that you can IMPORT one while building the other. Reported (and kindly explained) by Kevin Kofler. - Stick to one header file, though. While here, update copyright on file. --- src/libcalamares/DllMacro.h | 17 ++++++++++++++-- src/libcalamaresui/Branding.h | 2 +- src/libcalamaresui/CMakeLists.txt | 2 +- src/libcalamaresui/ViewManager.h | 2 +- .../modulesystem/CppJobModule.h | 2 +- src/libcalamaresui/modulesystem/Module.h | 2 +- .../modulesystem/ProcessJobModule.h | 2 +- .../modulesystem/PythonJobModule.h | 2 +- .../modulesystem/PythonQtViewModule.h | 2 +- src/libcalamaresui/modulesystem/ViewModule.h | 2 +- src/libcalamaresui/utils/CalamaresUtilsGui.h | 20 +++++++++---------- src/libcalamaresui/utils/ImageRegistry.h | 2 +- src/libcalamaresui/utils/Qml.h | 2 +- src/libcalamaresui/viewpages/ViewStep.h | 2 +- 14 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/libcalamares/DllMacro.h b/src/libcalamares/DllMacro.h index 9bb789c94..712bf5732 100644 --- a/src/libcalamares/DllMacro.h +++ b/src/libcalamares/DllMacro.h @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014, Teo Mrnjavac + * 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 @@ -22,8 +23,8 @@ #include /* - * Mark symbols exported from Calamares libraries with DLLEXPORT. - * These are the public API of the libraries. + * Mark symbols exported from Calamares non-GUI library with DLLEXPORT. + * These are the public API of libcalamares. */ #ifndef DLLEXPORT #if defined( DLLEXPORT_PRO ) @@ -33,6 +34,18 @@ #endif #endif +/* + * Mark symbols exported from Calamares GUI library with DLLEXPORT. + * These are the public API of libcalamaresui. + */ +#ifndef UIDLLEXPORT +#if defined( UIDLLEXPORT_PRO ) +#define UIDLLEXPORT Q_DECL_EXPORT +#else +#define UIDLLEXPORT Q_DECL_IMPORT +#endif +#endif + /* * Mark symbols exported from Calamares C++ plugins with PLUGINDLLEXPORT. * These are the public API of the libraries (generally, the plugin diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 4c051981c..f1b26fbb5 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -40,7 +40,7 @@ namespace Calamares class GlobalStorage; -class DLLEXPORT Branding : public QObject +class UIDLLEXPORT Branding : public QObject { Q_OBJECT public: diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index 9f87ed009..c603ca22d 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -66,7 +66,7 @@ endif() calamares_add_library( calamaresui SOURCES ${calamaresui_SOURCES} - EXPORT_MACRO DLLEXPORT_PRO + EXPORT_MACRO UIDLLEXPORT_PRO LINK_PRIVATE_LIBRARIES ${OPTIONAL_PYTHON_LIBRARIES} LINK_LIBRARIES diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index 50838f780..42fb9ad8f 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -33,7 +33,7 @@ namespace Calamares * @brief The ViewManager class handles progression through view pages. * @note Singleton object, only use through ViewManager::instance(). */ -class DLLEXPORT ViewManager : public QObject +class UIDLLEXPORT ViewManager : public QObject { Q_OBJECT public: diff --git a/src/libcalamaresui/modulesystem/CppJobModule.h b/src/libcalamaresui/modulesystem/CppJobModule.h index 758b44459..d97443a8a 100644 --- a/src/libcalamaresui/modulesystem/CppJobModule.h +++ b/src/libcalamaresui/modulesystem/CppJobModule.h @@ -29,7 +29,7 @@ class QPluginLoader; namespace Calamares { -class DLLEXPORT CppJobModule : public Module +class UIDLLEXPORT CppJobModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/Module.h b/src/libcalamaresui/modulesystem/Module.h index 4ebbdf2a2..0891f8a25 100644 --- a/src/libcalamaresui/modulesystem/Module.h +++ b/src/libcalamaresui/modulesystem/Module.h @@ -40,7 +40,7 @@ namespace Calamares * takes care of creating an object of the correct type starting from a module * descriptor structure. */ -class DLLEXPORT Module +class UIDLLEXPORT Module { public: /** diff --git a/src/libcalamaresui/modulesystem/ProcessJobModule.h b/src/libcalamaresui/modulesystem/ProcessJobModule.h index 31e3b1219..da2badbd0 100644 --- a/src/libcalamaresui/modulesystem/ProcessJobModule.h +++ b/src/libcalamaresui/modulesystem/ProcessJobModule.h @@ -29,7 +29,7 @@ namespace Calamares { -class DLLEXPORT ProcessJobModule : public Module +class UIDLLEXPORT ProcessJobModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/PythonJobModule.h b/src/libcalamaresui/modulesystem/PythonJobModule.h index 1d70b5f6c..295ab5942 100644 --- a/src/libcalamaresui/modulesystem/PythonJobModule.h +++ b/src/libcalamaresui/modulesystem/PythonJobModule.h @@ -26,7 +26,7 @@ namespace Calamares { -class DLLEXPORT PythonJobModule : public Module +class UIDLLEXPORT PythonJobModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/PythonQtViewModule.h b/src/libcalamaresui/modulesystem/PythonQtViewModule.h index eeee69a78..33b8d041b 100644 --- a/src/libcalamaresui/modulesystem/PythonQtViewModule.h +++ b/src/libcalamaresui/modulesystem/PythonQtViewModule.h @@ -27,7 +27,7 @@ namespace Calamares class ViewStep; -class DLLEXPORT PythonQtViewModule : public Module +class UIDLLEXPORT PythonQtViewModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/modulesystem/ViewModule.h b/src/libcalamaresui/modulesystem/ViewModule.h index dfe9bed92..c1ee8ff69 100644 --- a/src/libcalamaresui/modulesystem/ViewModule.h +++ b/src/libcalamaresui/modulesystem/ViewModule.h @@ -30,7 +30,7 @@ namespace Calamares class ViewStep; -class DLLEXPORT ViewModule : public Module +class UIDLLEXPORT ViewModule : public Module { public: Type type() const override; diff --git a/src/libcalamaresui/utils/CalamaresUtilsGui.h b/src/libcalamaresui/utils/CalamaresUtilsGui.h index 884e603e3..961ed5bc7 100644 --- a/src/libcalamaresui/utils/CalamaresUtilsGui.h +++ b/src/libcalamaresui/utils/CalamaresUtilsGui.h @@ -83,7 +83,7 @@ enum ImageMode * @param size the target pixmap size (default: original SVG size). * @return the new pixmap. */ -DLLEXPORT QPixmap defaultPixmap( ImageType type, +UIDLLEXPORT QPixmap defaultPixmap( ImageType type, ImageMode mode = CalamaresUtils::Original, const QSize& size = QSize( 0, 0 ) ); @@ -95,27 +95,27 @@ DLLEXPORT QPixmap defaultPixmap( ImageType type, * @return the transformed pixmap. * This one is currently unused. */ -DLLEXPORT QPixmap createRoundedImage( const QPixmap& avatar, const QSize& size, float frameWidthPct = 0.20f ); +UIDLLEXPORT QPixmap createRoundedImage( const QPixmap& avatar, const QSize& size, float frameWidthPct = 0.20f ); /** * @brief unmarginLayout recursively walks the QLayout tree and removes all margins. * @param layout the layout to unmargin. */ -DLLEXPORT void unmarginLayout( QLayout* layout ); +UIDLLEXPORT void unmarginLayout( QLayout* layout ); /** * @brief clearLayout recursively walks the QLayout tree and deletes all the child * widgets and layouts. * @param layout the layout to clear. */ -DLLEXPORT void clearLayout( QLayout* layout ); +UIDLLEXPORT void clearLayout( QLayout* layout ); -DLLEXPORT void setDefaultFontSize( int points ); -DLLEXPORT int defaultFontSize(); // in points -DLLEXPORT int defaultFontHeight(); // in pixels, DPI-specific -DLLEXPORT QFont defaultFont(); -DLLEXPORT QFont largeFont(); -DLLEXPORT QSize defaultIconSize(); +UIDLLEXPORT void setDefaultFontSize( int points ); +UIDLLEXPORT int defaultFontSize(); // in points +UIDLLEXPORT int defaultFontHeight(); // in pixels, DPI-specific +UIDLLEXPORT QFont defaultFont(); +UIDLLEXPORT QFont largeFont(); +UIDLLEXPORT QSize defaultIconSize(); /** * @brief Size constants for the main Calamares window. diff --git a/src/libcalamaresui/utils/ImageRegistry.h b/src/libcalamaresui/utils/ImageRegistry.h index a7d04fa9a..f73ee36e6 100644 --- a/src/libcalamaresui/utils/ImageRegistry.h +++ b/src/libcalamaresui/utils/ImageRegistry.h @@ -31,7 +31,7 @@ #include "DllMacro.h" #include "utils/CalamaresUtilsGui.h" -class DLLEXPORT ImageRegistry +class UIDLLEXPORT ImageRegistry { public: static ImageRegistry* instance(); diff --git a/src/libcalamaresui/utils/Qml.h b/src/libcalamaresui/utils/Qml.h index 70f59e7ec..7371bbc3a 100644 --- a/src/libcalamaresui/utils/Qml.h +++ b/src/libcalamaresui/utils/Qml.h @@ -34,7 +34,7 @@ namespace CalamaresUtils * * If there is a return value from the QML method, it is logged (but not otherwise used). */ -DLLEXPORT void +UIDLLEXPORT void callQMLFunction( QQuickItem* qmlObject, const char* method ); } // namespace CalamaresUtils diff --git a/src/libcalamaresui/viewpages/ViewStep.h b/src/libcalamaresui/viewpages/ViewStep.h index 55b2e200a..bdc235476 100644 --- a/src/libcalamaresui/viewpages/ViewStep.h +++ b/src/libcalamaresui/viewpages/ViewStep.h @@ -45,7 +45,7 @@ namespace Calamares * (which shows all of the things which have been collected to be done in the * next exec-step) through prettyStatus() and createSummaryWidget(). */ -class DLLEXPORT ViewStep : public QObject +class UIDLLEXPORT ViewStep : public QObject { Q_OBJECT public: From c5b45c37fc48d83bac7be24093f715af9ff65d22 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 18:10:46 +0100 Subject: [PATCH 46/78] [users] Add tests of the file-writing components --- src/modules/users/CMakeLists.txt | 11 ++- src/modules/users/SetHostNameJob.cpp | 6 +- src/modules/users/Tests.cpp | 124 +++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 src/modules/users/Tests.cpp diff --git a/src/modules/users/CMakeLists.txt b/src/modules/users/CMakeLists.txt index 6ee53806e..1d969a93b 100644 --- a/src/modules/users/CMakeLists.txt +++ b/src/modules/users/CMakeLists.txt @@ -41,10 +41,19 @@ calamares_add_plugin( users ) calamares_add_test( - passwordtest + userspasswordtest SOURCES PasswordTests.cpp SetPasswordJob.cpp LIBRARIES ${CRYPT_LIBRARIES} ) + +calamares_add_test( + userstest + SOURCES + Tests.cpp + SetHostNameJob.cpp + LIBRARIES + Qt5::DBus +) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index 62ef8cc1b..b43968f99 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -58,7 +58,7 @@ SetHostNameJob::prettyStatusMessage() const return tr( "Setting hostname %1." ).arg( m_hostname ); } -static bool +STATICTEST bool setFileHostname( const QString& hostname ) { return !( CalamaresUtils::System::instance() @@ -66,7 +66,7 @@ setFileHostname( const QString& hostname ) .failed() ); } -static bool +STATICTEST bool writeFileEtcHosts( const QString& hostname ) { // The actual hostname gets substituted in at %1 @@ -83,7 +83,7 @@ ff02::2 ip6-allrouters .failed() ); } -static void +STATICTEST void setSystemdHostname( const QString& hostname ) { QDBusInterface hostnamed( "org.freedesktop.hostname1", diff --git a/src/modules/users/Tests.cpp b/src/modules/users/Tests.cpp new file mode 100644 index 000000000..db02c5a10 --- /dev/null +++ b/src/modules/users/Tests.cpp @@ -0,0 +1,124 @@ +/* === This file is part of Calamares - === + * + * 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 + * 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 "SetHostNameJob.h" + +// Implementation details +extern bool setFileHostname( const QString& ); +extern bool writeFileEtcHosts( const QString& ); +extern void setSystemdHostname( const QString& ); + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" +#include "utils/Yaml.h" + +#include +#include + +class UsersTests : public QObject +{ + Q_OBJECT +public: + UsersTests(); + virtual ~UsersTests() {} + +private Q_SLOTS: + void initTestCase(); + + void testEtcHostname(); + void testEtcHosts(); + +private: + QTemporaryDir m_dir; +}; + +UsersTests::UsersTests() + : m_dir( QStringLiteral( "/tmp/calamares-usertest" ) ) +{ + // Would want to do this if the test fails, automatically. + // + // m_dir.setAutoRemove( false ); +} + +void UsersTests::initTestCase() +{ + Logger::setupLogLevel( Logger::LOGDEBUG ); + cDebug() << "Users test started."; + cDebug() << "Test dir" << m_dir.path(); + + // Ensure we have a system object, expect it to be a "bogus" one + CalamaresUtils::System* system = CalamaresUtils::System::instance(); + QVERIFY( system ); + QVERIFY( system->doChroot() ); + + // Ensure we have a system-wide GlobalStorage with /tmp as root + if ( !Calamares::JobQueue::instance() ) + { + cDebug() << "Creating new JobQueue"; + (void)new Calamares::JobQueue(); + } + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + QVERIFY( gs ); + gs->insert( "rootMountPoint", m_dir.path() ); +} + +void UsersTests::testEtcHostname() +{ + cDebug() << "Test dir" << m_dir.path(); + + QVERIFY( QFile::exists( m_dir.path() ) ); + QVERIFY( !QFile::exists( m_dir.filePath( "etc" ) ) ); + + // Doesn't create intermediate directories + QVERIFY( !setFileHostname( QStringLiteral( "tubophone.calamares.io" ) ) ); + + QVERIFY( CalamaresUtils::System::instance()->createTargetDirs( "/etc" ) ); + QVERIFY( QFile::exists( m_dir.filePath( "etc" ) ) ); + + // Does write the file + QVERIFY( setFileHostname( QStringLiteral( "tubophone.calamares.io" ) ) ); + QVERIFY( QFile::exists( m_dir.filePath( "etc/hostname" ) ) ); + + // 22 for the test string, above, and 1 for the newline + QCOMPARE( QFileInfo( m_dir.filePath("etc/hostname") ).size(), 22 + 1); +} + +void UsersTests::testEtcHosts() +{ + // Assume previous tests did their work + QVERIFY( QFile::exists( m_dir.path() ) ); + QVERIFY( QFile::exists( m_dir.filePath( "etc" ) ) ); + + QVERIFY( writeFileEtcHosts( QStringLiteral( "tubophone.calamares.io" ) ) ); + QVERIFY( QFile::exists( m_dir.filePath( "etc/hosts" ) ) ); + // The skeleton contains %1 which has the hostname substituted in, so we lose two, + // and the rest of the blabla is 150 (according to Python) + QCOMPARE( QFileInfo( m_dir.filePath("etc/hosts") ).size(), 150 + 22 - 2 ); +} + + + +QTEST_GUILESS_MAIN( UsersTests ) + +#include "utils/moc-warnings.h" + +#include "Tests.moc" + From f1435452ea9d446ac6de42f194214e595ac5d463 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Feb 2020 18:21:44 +0100 Subject: [PATCH 47/78] [users] Polish up tests - Don't remove test artifacts on failure - Coding style --- src/modules/users/Tests.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/modules/users/Tests.cpp b/src/modules/users/Tests.cpp index db02c5a10..3c1d2d25d 100644 --- a/src/modules/users/Tests.cpp +++ b/src/modules/users/Tests.cpp @@ -45,6 +45,8 @@ private Q_SLOTS: void testEtcHostname(); void testEtcHosts(); + void cleanup(); + private: QTemporaryDir m_dir; }; @@ -52,12 +54,10 @@ private: UsersTests::UsersTests() : m_dir( QStringLiteral( "/tmp/calamares-usertest" ) ) { - // Would want to do this if the test fails, automatically. - // - // m_dir.setAutoRemove( false ); } -void UsersTests::initTestCase() +void +UsersTests::initTestCase() { Logger::setupLogLevel( Logger::LOGDEBUG ); cDebug() << "Users test started."; @@ -80,7 +80,8 @@ void UsersTests::initTestCase() gs->insert( "rootMountPoint", m_dir.path() ); } -void UsersTests::testEtcHostname() +void +UsersTests::testEtcHostname() { cDebug() << "Test dir" << m_dir.path(); @@ -98,10 +99,11 @@ void UsersTests::testEtcHostname() QVERIFY( QFile::exists( m_dir.filePath( "etc/hostname" ) ) ); // 22 for the test string, above, and 1 for the newline - QCOMPARE( QFileInfo( m_dir.filePath("etc/hostname") ).size(), 22 + 1); + QCOMPARE( QFileInfo( m_dir.filePath( "etc/hostname" ) ).size(), 22 + 1 ); } -void UsersTests::testEtcHosts() +void +UsersTests::testEtcHosts() { // Assume previous tests did their work QVERIFY( QFile::exists( m_dir.path() ) ); @@ -111,9 +113,17 @@ void UsersTests::testEtcHosts() QVERIFY( QFile::exists( m_dir.filePath( "etc/hosts" ) ) ); // The skeleton contains %1 which has the hostname substituted in, so we lose two, // and the rest of the blabla is 150 (according to Python) - QCOMPARE( QFileInfo( m_dir.filePath("etc/hosts") ).size(), 150 + 22 - 2 ); + QCOMPARE( QFileInfo( m_dir.filePath( "etc/hosts" ) ).size(), 150 + 22 - 2 ); } +void +UsersTests::cleanup() +{ + if ( QTest::currentTestFailed() ) + { + m_dir.setAutoRemove( false ); + } +} QTEST_GUILESS_MAIN( UsersTests ) @@ -121,4 +131,3 @@ QTEST_GUILESS_MAIN( UsersTests ) #include "utils/moc-warnings.h" #include "Tests.moc" - From 094c213baa2b07e55b22bd59af3aba4424b80715 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 10:16:19 +0100 Subject: [PATCH 48/78] [users] Also test hostname-setting via hostnamed SEE #1140 --- src/modules/users/SetHostNameJob.cpp | 12 +++++++++++- src/modules/users/Tests.cpp | 14 +++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index b43968f99..98343027b 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -83,20 +83,27 @@ ff02::2 ip6-allrouters .failed() ); } -STATICTEST void +STATICTEST bool setSystemdHostname( const QString& hostname ) { QDBusInterface hostnamed( "org.freedesktop.hostname1", "/org/freedesktop/hostname1", "org.freedesktop.hostname1", QDBusConnection::systemBus() ); + if ( !hostnamed.isValid() ) + { + cWarning() << "Interface" << hostnamed.interface() << "is not valid."; + return false; + } + bool success = true; // Static, writes /etc/hostname { QDBusReply< uint > r = hostnamed.call( "SetStaticHostname", hostname, false ); if ( !r.isValid() ) { cWarning() << "Could not set hostname through org.freedesktop.hostname1.SetStaticHostname." << r.error(); + success = false; } } // Dynamic, updates kernel @@ -105,8 +112,11 @@ setSystemdHostname( const QString& hostname ) if ( !r.isValid() ) { cWarning() << "Could not set hostname through org.freedesktop.hostname1.SetHostname." << r.error(); + success = false; } } + + return success; } diff --git a/src/modules/users/Tests.cpp b/src/modules/users/Tests.cpp index 3c1d2d25d..196fd9d68 100644 --- a/src/modules/users/Tests.cpp +++ b/src/modules/users/Tests.cpp @@ -21,7 +21,7 @@ // Implementation details extern bool setFileHostname( const QString& ); extern bool writeFileEtcHosts( const QString& ); -extern void setSystemdHostname( const QString& ); +extern bool setSystemdHostname( const QString& ); #include "GlobalStorage.h" #include "JobQueue.h" @@ -44,6 +44,7 @@ private Q_SLOTS: void testEtcHostname(); void testEtcHosts(); + void testHostnamed(); void cleanup(); @@ -116,6 +117,17 @@ UsersTests::testEtcHosts() QCOMPARE( QFileInfo( m_dir.filePath( "etc/hosts" ) ).size(), 150 + 22 - 2 ); } +void +UsersTests::testHostnamed() +{ + // Since the service might not be running (e.g. non-systemd systems, + // FreeBSD, docker, ..) we're not going to fail a test here. + // There's also the permissions problem to think of. + QEXPECT_FAIL( "", "Hostname changes are access-controlled", Continue ); + QVERIFY( setSystemdHostname( "tubophone.calamares.io" ) ); +} + + void UsersTests::cleanup() { From f7e8488edf1c0f685e710bf4b75fd78899f2ca16 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 10:35:47 +0100 Subject: [PATCH 49/78] [users] Correct DBus return from hostnamed calls --- src/modules/users/SetHostNameJob.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index 98343027b..a3388ec98 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -99,7 +99,7 @@ setSystemdHostname( const QString& hostname ) bool success = true; // Static, writes /etc/hostname { - QDBusReply< uint > r = hostnamed.call( "SetStaticHostname", hostname, false ); + QDBusReply< void > r = hostnamed.call( "SetStaticHostname", hostname, false ); if ( !r.isValid() ) { cWarning() << "Could not set hostname through org.freedesktop.hostname1.SetStaticHostname." << r.error(); @@ -108,7 +108,7 @@ setSystemdHostname( const QString& hostname ) } // Dynamic, updates kernel { - QDBusReply< uint > r = hostnamed.call( "SetHostname", hostname, false ); + QDBusReply< void > r = hostnamed.call( "SetHostname", hostname, false ); if ( !r.isValid() ) { cWarning() << "Could not set hostname through org.freedesktop.hostname1.SetHostname." << r.error(); From 7c2a1965682dceea541bb2f0c2ce16b86c0b5258 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 10:38:31 +0100 Subject: [PATCH 50/78] [users] Document new knobs - while here, update copyright notice FIXES #1140 --- CHANGES | 3 +++ src/modules/users/SetHostNameJob.cpp | 2 +- src/modules/users/SetHostNameJob.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index cb807cdc4..4bc35f2d5 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,9 @@ This release contains contributions from (alphabetically by first name): "fancy" release notes as a QML application, rather than a webview or text widget. Note that this does not replace the slideshow-during- installation module. + - The *users* module now has knobs for setting the hostname and writing + the `/etc/hosts` file. The new configuration options are documented + in `users.conf`. #1140 # 3.2.18 (2020-01-28) # diff --git a/src/modules/users/SetHostNameJob.cpp b/src/modules/users/SetHostNameJob.cpp index a3388ec98..db220d042 100644 --- a/src/modules/users/SetHostNameJob.cpp +++ b/src/modules/users/SetHostNameJob.cpp @@ -2,7 +2,7 @@ * * Copyright 2014, Rohan Garg * Copyright 2015, Teo Mrnjavac - * Copyright 2018, Adriaan de Groot + * Copyright 2018, 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 diff --git a/src/modules/users/SetHostNameJob.h b/src/modules/users/SetHostNameJob.h index e4c2f2510..619e2ba59 100644 --- a/src/modules/users/SetHostNameJob.h +++ b/src/modules/users/SetHostNameJob.h @@ -2,6 +2,7 @@ * * Copyright 2014, Rohan Garg * Copyright 2015, Teo Mrnjavac + * 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 From 17eb3f5e33e35e778d2064fd615101a8bd4b5ae1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 11:02:53 +0100 Subject: [PATCH 51/78] [netinstall] Apply coding style --- src/modules/netinstall/NetInstallViewStep.cpp | 19 ++- src/modules/netinstall/NetInstallViewStep.h | 2 +- src/modules/netinstall/PackageModel.cpp | 151 ++++++++++++------ src/modules/netinstall/PackageModel.h | 21 ++- src/modules/netinstall/PackageTreeItem.cpp | 55 +++++-- src/modules/netinstall/PackageTreeItem.h | 9 +- 6 files changed, 167 insertions(+), 90 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index fcb76be5a..94efb5f86 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -20,15 +20,15 @@ #include "NetInstallViewStep.h" -#include "JobQueue.h" #include "GlobalStorage.h" +#include "JobQueue.h" #include "utils/Logger.h" #include "utils/Variant.h" #include "NetInstallPage.h" -CALAMARES_PLUGIN_FACTORY_DEFINITION( NetInstallViewStepFactory, registerPlugin(); ) +CALAMARES_PLUGIN_FACTORY_DEFINITION( NetInstallViewStepFactory, registerPlugin< NetInstallViewStep >(); ) NetInstallViewStep::NetInstallViewStep( QObject* parent ) : Calamares::ViewStep( parent ) @@ -36,15 +36,16 @@ NetInstallViewStep::NetInstallViewStep( QObject* parent ) , m_nextEnabled( false ) { emit nextStatusChanged( true ); - connect( m_widget, &NetInstallPage::checkReady, - this, &NetInstallViewStep::nextIsReady ); + connect( m_widget, &NetInstallPage::checkReady, this, &NetInstallViewStep::nextIsReady ); } NetInstallViewStep::~NetInstallViewStep() { if ( m_widget && m_widget->parent() == nullptr ) + { m_widget->deleteLater(); + } } @@ -131,28 +132,32 @@ NetInstallViewStep::onLeave() // with the more complicated datastructure. if ( !package.preScript.isEmpty() || !package.postScript.isEmpty() ) { - QMap sdetails; + QMap< QString, QVariant > sdetails; sdetails.insert( "pre-script", package.preScript ); sdetails.insert( "package", package.packageName ); sdetails.insert( "post-script", package.postScript ); details = sdetails; } if ( package.isCritical ) + { installPackages.append( details ); + } else + { tryInstallPackages.append( details ); + } } if ( !installPackages.empty() ) { - QMap op; + QMap< QString, QVariant > op; op.insert( "install", QVariant( installPackages ) ); packageOperations.append( op ); cDebug() << Logger::SubEntry << installPackages.length() << "critical packages."; } if ( !tryInstallPackages.empty() ) { - QMap op; + QMap< QString, QVariant > op; op.insert( "try_install", QVariant( tryInstallPackages ) ); packageOperations.append( op ); cDebug() << Logger::SubEntry << tryInstallPackages.length() << "non-critical packages."; diff --git a/src/modules/netinstall/NetInstallViewStep.h b/src/modules/netinstall/NetInstallViewStep.h index f26ba74ed..be92f5cc3 100644 --- a/src/modules/netinstall/NetInstallViewStep.h +++ b/src/modules/netinstall/NetInstallViewStep.h @@ -70,4 +70,4 @@ private: CALAMARES_PLUGIN_FACTORY_DECLARATION( NetInstallViewStepFactory ) -#endif // NETINSTALLVIEWSTEP_H +#endif // NETINSTALLVIEWSTEP_H diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index 2fde7695e..331586869 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -21,9 +21,9 @@ #include "utils/Yaml.h" -PackageModel::PackageModel( const YAML::Node& data, QObject* parent ) : - QAbstractItemModel( parent ), - m_columnHeadings() +PackageModel::PackageModel( const YAML::Node& data, QObject* parent ) + : QAbstractItemModel( parent ) + , m_columnHeadings() { m_rootItem = new PackageTreeItem(); setupModelData( data, m_rootItem ); @@ -38,33 +38,47 @@ QModelIndex PackageModel::index( int row, int column, const QModelIndex& parent ) const { if ( !hasIndex( row, column, parent ) ) + { return QModelIndex(); + } PackageTreeItem* parentItem; if ( !parent.isValid() ) + { parentItem = m_rootItem; + } else - parentItem = static_cast( parent.internalPointer() ); + { + parentItem = static_cast< PackageTreeItem* >( parent.internalPointer() ); + } PackageTreeItem* childItem = parentItem->child( row ); if ( childItem ) + { return createIndex( row, column, childItem ); + } else + { return QModelIndex(); + } } QModelIndex PackageModel::parent( const QModelIndex& index ) const { if ( !index.isValid() ) + { return QModelIndex(); + } - PackageTreeItem* child = static_cast( index.internalPointer() ); + PackageTreeItem* child = static_cast< PackageTreeItem* >( index.internalPointer() ); PackageTreeItem* parent = child->parentItem(); if ( parent == m_rootItem ) + { return QModelIndex(); + } return createIndex( parent->row(), 0, parent ); } @@ -72,13 +86,19 @@ int PackageModel::rowCount( const QModelIndex& parent ) const { if ( parent.column() > 0 ) + { return 0; + } PackageTreeItem* parentItem; if ( !parent.isValid() ) + { parentItem = m_rootItem; + } else - parentItem = static_cast( parent.internalPointer() ); + { + parentItem = static_cast< PackageTreeItem* >( parent.internalPointer() ); + } return parentItem->childCount(); } @@ -87,7 +107,9 @@ int PackageModel::columnCount( const QModelIndex& parent ) const { if ( parent.isValid() ) - return static_cast( parent.internalPointer() )->columnCount(); + { + return static_cast< PackageTreeItem* >( parent.internalPointer() )->columnCount(); + } return m_rootItem->columnCount(); } @@ -95,17 +117,25 @@ QVariant PackageModel::data( const QModelIndex& index, int role ) const { if ( !index.isValid() ) + { return QVariant(); + } - PackageTreeItem* item = static_cast( index.internalPointer() ); + PackageTreeItem* item = static_cast< PackageTreeItem* >( index.internalPointer() ); if ( index.column() == 0 && role == Qt::CheckStateRole ) + { return item->isSelected(); + } - if ( item->isHidden() && role == Qt::DisplayRole ) // Hidden group + if ( item->isHidden() && role == Qt::DisplayRole ) // Hidden group + { return QVariant(); + } if ( role == Qt::DisplayRole ) + { return item->data( index.column() ); + } return QVariant(); } @@ -114,27 +144,31 @@ PackageModel::setData( const QModelIndex& index, const QVariant& value, int role { if ( role == Qt::CheckStateRole && index.isValid() ) { - PackageTreeItem* item = static_cast( index.internalPointer() ); - item->setSelected( static_cast( value.toInt() ) ); + PackageTreeItem* item = static_cast< PackageTreeItem* >( index.internalPointer() ); + item->setSelected( static_cast< Qt::CheckState >( value.toInt() ) ); - emit dataChanged( this->index( 0, 0 ), index.sibling( index.column(), index.row() + 1 ), - QVector( Qt::CheckStateRole ) ); + emit dataChanged( this->index( 0, 0 ), + index.sibling( index.column(), index.row() + 1 ), + QVector< int >( Qt::CheckStateRole ) ); } return true; } bool -PackageModel::setHeaderData( int section, Qt::Orientation orientation, - const QVariant& value, int role ) +PackageModel::setHeaderData( int section, Qt::Orientation orientation, const QVariant& value, int role ) { Q_UNUSED( role ) if ( orientation == Qt::Horizontal ) { if ( m_columnHeadings.value( section ) != QVariant() ) + { m_columnHeadings.replace( section, value ); + } else + { m_columnHeadings.insert( section, value ); + } emit headerDataChanged( orientation, section, section ); } return true; @@ -144,9 +178,13 @@ Qt::ItemFlags PackageModel::flags( const QModelIndex& index ) const { if ( !index.isValid() ) + { return Qt::ItemFlags(); + } if ( index.column() == 0 ) + { return Qt::ItemIsUserCheckable | QAbstractItemModel::flags( index ); + } return QAbstractItemModel::flags( index ); } @@ -154,46 +192,55 @@ QVariant PackageModel::headerData( int section, Qt::Orientation orientation, int role ) const { if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) + { return m_columnHeadings.value( section ); + } return QVariant(); } -QList +QList< PackageTreeItem::ItemData > PackageModel::getPackages() const { - QList items = getItemPackages( m_rootItem ); + QList< PackageTreeItem* > items = getItemPackages( m_rootItem ); for ( auto package : m_hiddenItems ) if ( package->hiddenSelected() ) + { items.append( getItemPackages( package ) ); - QList packages; + } + QList< PackageTreeItem::ItemData > packages; for ( auto item : items ) { PackageTreeItem::ItemData itemData; - itemData.preScript = item->parentItem()->preScript(); // Only groups have hooks - itemData.packageName = item->packageName(); // this seg faults - itemData.postScript = item->parentItem()->postScript(); // Only groups have hooks - itemData.isCritical = item->parentItem()->isCritical(); // Only groups are critical + itemData.preScript = item->parentItem()->preScript(); // Only groups have hooks + itemData.packageName = item->packageName(); // this seg faults + itemData.postScript = item->parentItem()->postScript(); // Only groups have hooks + itemData.isCritical = item->parentItem()->isCritical(); // Only groups are critical packages.append( itemData ); } return packages; } -QList +QList< PackageTreeItem* > PackageModel::getItemPackages( PackageTreeItem* item ) const { - QList selectedPackages; + QList< PackageTreeItem* > selectedPackages; for ( int i = 0; i < item->childCount(); i++ ) { if ( item->child( i )->isSelected() == Qt::Unchecked ) + { continue; + } - if ( !item->child( i )->childCount() ) // package + if ( !item->child( i )->childCount() ) // package + { selectedPackages.append( item->child( i ) ); + } else + { selectedPackages.append( getItemPackages( item->child( i ) ) ); + } } return selectedPackages; - } void @@ -203,49 +250,49 @@ PackageModel::setupModelData( const YAML::Node& data, PackageTreeItem* parent ) { const YAML::Node itemDefinition = *it; - QString name( - tr( CalamaresUtils::yamlToVariant( itemDefinition["name"] ).toByteArray() ) ); - QString description( - tr( CalamaresUtils::yamlToVariant( itemDefinition["description"] ).toByteArray() ) ); + QString name( tr( CalamaresUtils::yamlToVariant( itemDefinition[ "name" ] ).toByteArray() ) ); + QString description( tr( CalamaresUtils::yamlToVariant( itemDefinition[ "description" ] ).toByteArray() ) ); PackageTreeItem::ItemData itemData; itemData.name = name; itemData.description = description; - if ( itemDefinition["pre-install"] ) - itemData.preScript = - CalamaresUtils::yamlToVariant( itemDefinition["pre-install"] ).toString(); - if ( itemDefinition["post-install"] ) - itemData.postScript = - CalamaresUtils::yamlToVariant( itemDefinition["post-install"] ).toString(); + if ( itemDefinition[ "pre-install" ] ) + itemData.preScript = CalamaresUtils::yamlToVariant( itemDefinition[ "pre-install" ] ).toString(); + if ( itemDefinition[ "post-install" ] ) + itemData.postScript = CalamaresUtils::yamlToVariant( itemDefinition[ "post-install" ] ).toString(); PackageTreeItem* item = new PackageTreeItem( itemData, parent ); - if ( itemDefinition["selected"] ) - item->setSelected( - CalamaresUtils::yamlToVariant( itemDefinition["selected"] ).toBool() ? - Qt::Checked : Qt::Unchecked ); + if ( itemDefinition[ "selected" ] ) + item->setSelected( CalamaresUtils::yamlToVariant( itemDefinition[ "selected" ] ).toBool() ? Qt::Checked + : Qt::Unchecked ); else - item->setSelected( parent->isSelected() ); // Inherit from it's parent + { + item->setSelected( parent->isSelected() ); // Inherit from it's parent + } - if ( itemDefinition["hidden"] ) - item->setHidden( - CalamaresUtils::yamlToVariant( itemDefinition["hidden"] ).toBool() ); + if ( itemDefinition[ "hidden" ] ) + item->setHidden( CalamaresUtils::yamlToVariant( itemDefinition[ "hidden" ] ).toBool() ); - if ( itemDefinition["critical"] ) - item->setCritical( - CalamaresUtils::yamlToVariant( itemDefinition["critical"] ).toBool() ); + if ( itemDefinition[ "critical" ] ) + item->setCritical( CalamaresUtils::yamlToVariant( itemDefinition[ "critical" ] ).toBool() ); - if ( itemDefinition["packages"] ) - for ( YAML::const_iterator packageIt = itemDefinition["packages"].begin(); - packageIt != itemDefinition["packages"].end(); ++packageIt ) + if ( itemDefinition[ "packages" ] ) + for ( YAML::const_iterator packageIt = itemDefinition[ "packages" ].begin(); + packageIt != itemDefinition[ "packages" ].end(); + ++packageIt ) item->appendChild( new PackageTreeItem( CalamaresUtils::yamlToVariant( *packageIt ).toString(), item ) ); - if ( itemDefinition["subgroups"] ) - setupModelData( itemDefinition["subgroups"], item ); + if ( itemDefinition[ "subgroups" ] ) + { + setupModelData( itemDefinition[ "subgroups" ], item ); + } if ( item->isHidden() ) + { m_hiddenItems.append( item ); + } else { item->setCheckable( true ); diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index f84b2779d..cd8f676c8 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -29,7 +29,7 @@ namespace YAML { - class Node; +class Node; } class PackageModel : public QAbstractItemModel @@ -43,27 +43,24 @@ public: ~PackageModel() override; QVariant data( const QModelIndex& index, int role ) const override; - bool setData( const QModelIndex& index, const QVariant& value, - int role = Qt::EditRole ) override; - bool setHeaderData( int section, Qt::Orientation orientation, - const QVariant& value, int role = Qt::EditRole ) override; + bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) override; + bool + setHeaderData( int section, Qt::Orientation orientation, const QVariant& value, int role = Qt::EditRole ) override; Qt::ItemFlags flags( const QModelIndex& index ) const override; - QVariant headerData( int section, Qt::Orientation orientation, - int role = Qt::DisplayRole ) const override; - QModelIndex index( int row, int column, - const QModelIndex& parent = QModelIndex() ) const override; + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; + QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const override; QModelIndex parent( const QModelIndex& index ) const override; int rowCount( const QModelIndex& parent = QModelIndex() ) const override; int columnCount( const QModelIndex& parent = QModelIndex() ) const override; PackageItemDataList getPackages() const; - QList getItemPackages( PackageTreeItem* item ) const; + QList< PackageTreeItem* > getItemPackages( PackageTreeItem* item ) const; private: void setupModelData( const YAML::Node& data, PackageTreeItem* parent ); PackageTreeItem* m_rootItem; - QList m_hiddenItems; + QList< PackageTreeItem* > m_hiddenItems; QVariantList m_columnHeadings; }; -#endif // PACKAGEMODEL_H +#endif // PACKAGEMODEL_H diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index b3dc6fae7..0b4dfb694 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -24,25 +24,30 @@ PackageTreeItem::PackageTreeItem( const ItemData& data, PackageTreeItem* parent ) : m_parentItem( parent ) , m_data( data ) -{ } +{ +} -PackageTreeItem::PackageTreeItem( const QString packageName, PackageTreeItem* parent ) : - m_parentItem( parent ) +PackageTreeItem::PackageTreeItem( const QString packageName, PackageTreeItem* parent ) + : m_parentItem( parent ) { m_data.packageName = packageName; if ( parent != nullptr ) + { m_data.selected = parent->isSelected(); + } else + { m_data.selected = Qt::Unchecked; + } } -PackageTreeItem::PackageTreeItem( PackageTreeItem* parent ) : - m_parentItem( parent ) +PackageTreeItem::PackageTreeItem( PackageTreeItem* parent ) + : m_parentItem( parent ) { } -PackageTreeItem::PackageTreeItem::PackageTreeItem() : - PackageTreeItem( QString(), nullptr ) +PackageTreeItem::PackageTreeItem::PackageTreeItem() + : PackageTreeItem( QString(), nullptr ) { m_data.selected = Qt::Checked; m_data.name = QLatin1String( "" ); @@ -75,7 +80,9 @@ int PackageTreeItem::row() const { if ( m_parentItem ) - return m_parentItem->m_childItems.indexOf( const_cast( this ) ); + { + return m_parentItem->m_childItems.indexOf( const_cast< PackageTreeItem* >( this ) ); + } return 0; } @@ -88,13 +95,15 @@ PackageTreeItem::columnCount() const QVariant PackageTreeItem::data( int column ) const { - if ( packageName() != nullptr ) // package + if ( packageName() != nullptr ) // package { if ( !column ) + { return QVariant( packageName() ); + } return QVariant(); } - switch ( column ) // group + switch ( column ) // group { case 0: return QVariant( prettyName() ); @@ -164,14 +173,18 @@ bool PackageTreeItem::hiddenSelected() const { Q_ASSERT( m_data.isHidden ); - if (! m_data.selected ) + if ( !m_data.selected ) + { return false; + } const PackageTreeItem* currentItem = parentItem(); while ( currentItem != nullptr ) { if ( !currentItem->isHidden() ) + { return currentItem->isSelected() != Qt::Unchecked; + } currentItem = currentItem->parentItem(); } @@ -202,8 +215,10 @@ void PackageTreeItem::setSelected( Qt::CheckState isSelected ) { if ( parentItem() == nullptr ) - // This is the root, it is always checked so don't change state + // This is the root, it is always checked so don't change state + { return; + } m_data.selected = isSelected; setChildrenSelected( isSelected ); @@ -216,8 +231,10 @@ PackageTreeItem::setSelected( Qt::CheckState isSelected ) currentItem = currentItem->parentItem(); } if ( currentItem == nullptr ) - // Reached the root .. don't bother + // Reached the root .. don't bother + { return; + } // Figure out checked-state based on the children int childrenSelected = 0; @@ -225,16 +242,26 @@ PackageTreeItem::setSelected( Qt::CheckState isSelected ) for ( int i = 0; i < currentItem->childCount(); i++ ) { if ( currentItem->child( i )->isSelected() == Qt::Checked ) + { childrenSelected++; + } if ( currentItem->child( i )->isSelected() == Qt::PartiallyChecked ) + { childrenPartiallySelected++; + } } - if ( !childrenSelected && !childrenPartiallySelected) + if ( !childrenSelected && !childrenPartiallySelected ) + { currentItem->setSelected( Qt::Unchecked ); + } else if ( childrenSelected == currentItem->childCount() ) + { currentItem->setSelected( Qt::Checked ); + } else + { currentItem->setSelected( Qt::PartiallyChecked ); + } } void diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index 9c1c8c5a5..c35dc5733 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -21,8 +21,8 @@ #define PACKAGETREEITEM_H #include -#include #include +#include class PackageTreeItem : public QStandardItem { @@ -78,11 +78,12 @@ public: void setSelected( Qt::CheckState isSelected ); void setChildrenSelected( Qt::CheckState isSelected ); int type() const override; + private: PackageTreeItem* m_parentItem; - QList m_childItems; + QList< PackageTreeItem* > m_childItems; ItemData m_data; - const int m_columns = 2; // Name, description + const int m_columns = 2; // Name, description }; -#endif // PACKAGETREEITEM_H +#endif // PACKAGETREEITEM_H From 8286bff95fe945604aeebd40f9eee8274c2e260c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 11:28:42 +0100 Subject: [PATCH 52/78] [netinstall] Shuffle code around a bit - introduce char const for key name (consistency, it's used lots) - polish debugging a bit - add some inline code-docs --- src/modules/netinstall/NetInstallViewStep.cpp | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 94efb5f86..be163a422 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -115,15 +115,21 @@ NetInstallViewStep::onActivate() void NetInstallViewStep::onLeave() { - cDebug() << "Leaving netinstall, adding packages to be installed" - << "to global storage"; - PackageModel::PackageItemDataList packages = m_widget->selectedPackages(); + cDebug() << "Netinstall: Processing" << packages.length() << "packages."; + + static const char PACKAGEOP[] = "packageOperations"; + + // Check if there's already a PACAKGEOP entry in GS, and if so we'll + // extend that one (overwriting the value in GS at the end of this method) + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + QVariantList packageOperations = gs->contains( PACKAGEOP ) ? gs->value( PACKAGEOP ).toList() : QVariantList(); + cDebug() << Logger::SubEntry << "Existing package operations length" << packageOperations.length(); + + // This netinstall module may add two sub-steps to the packageOperations, + // one for installing and one for try-installing. QVariantList installPackages; QVariantList tryInstallPackages; - QVariantList packageOperations; - - cDebug() << "Processing" << packages.length() << "packages from netinstall."; for ( auto package : packages ) { @@ -165,8 +171,7 @@ NetInstallViewStep::onLeave() if ( !packageOperations.isEmpty() ) { - Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - gs->insert( "packageOperations", QVariant( packageOperations ) ); + gs->insert( PACKAGEOP, packageOperations ); } } From d5675508fa4c02de55447c88ebb52947e69b01f7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 11:39:54 +0100 Subject: [PATCH 53/78] [netinstall] More coding-style The tools don't always pick up all the style changes in one go (I think astyle has trouble parsing some Calamares code) --- src/modules/netinstall/PackageModel.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index 331586869..b5b256ae0 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -258,9 +258,13 @@ PackageModel::setupModelData( const YAML::Node& data, PackageTreeItem* parent ) itemData.description = description; if ( itemDefinition[ "pre-install" ] ) + { itemData.preScript = CalamaresUtils::yamlToVariant( itemDefinition[ "pre-install" ] ).toString(); + } if ( itemDefinition[ "post-install" ] ) + { itemData.postScript = CalamaresUtils::yamlToVariant( itemDefinition[ "post-install" ] ).toString(); + } PackageTreeItem* item = new PackageTreeItem( itemData, parent ); if ( itemDefinition[ "selected" ] ) @@ -272,10 +276,14 @@ PackageModel::setupModelData( const YAML::Node& data, PackageTreeItem* parent ) } if ( itemDefinition[ "hidden" ] ) + { item->setHidden( CalamaresUtils::yamlToVariant( itemDefinition[ "hidden" ] ).toBool() ); + } if ( itemDefinition[ "critical" ] ) + { item->setCritical( CalamaresUtils::yamlToVariant( itemDefinition[ "critical" ] ).toBool() ); + } if ( itemDefinition[ "packages" ] ) for ( YAML::const_iterator packageIt = itemDefinition[ "packages" ].begin(); From 056b0d7548de342277d3fc50ddb8f8ff274a2d6f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 11:40:43 +0100 Subject: [PATCH 54/78] [netinstall] Refactor variant-from-ItemData --- src/modules/netinstall/NetInstallViewStep.cpp | 18 +++--------------- src/modules/netinstall/PackageTreeItem.cpp | 19 +++++++++++++++++++ src/modules/netinstall/PackageTreeItem.h | 7 +++++++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index be163a422..53250ba13 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -111,7 +111,6 @@ NetInstallViewStep::onActivate() m_widget->onActivate(); } - void NetInstallViewStep::onLeave() { @@ -131,26 +130,15 @@ NetInstallViewStep::onLeave() QVariantList installPackages; QVariantList tryInstallPackages; - for ( auto package : packages ) + for ( const auto& package : packages ) { - QVariant details( package.packageName ); - // If it's a package with a pre- or post-script, replace - // with the more complicated datastructure. - if ( !package.preScript.isEmpty() || !package.postScript.isEmpty() ) - { - QMap< QString, QVariant > sdetails; - sdetails.insert( "pre-script", package.preScript ); - sdetails.insert( "package", package.packageName ); - sdetails.insert( "post-script", package.postScript ); - details = sdetails; - } if ( package.isCritical ) { - installPackages.append( details ); + installPackages.append( package.toOperation() ); } else { - tryInstallPackages.append( details ); + tryInstallPackages.append( package.toOperation() ); } } diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index 0b4dfb694..bbd85975e 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -21,6 +21,25 @@ #include "utils/Logger.h" +QVariant +PackageTreeItem::ItemData::toOperation() const +{ + // If it's a package with a pre- or post-script, replace + // with the more complicated datastructure. + if ( !preScript.isEmpty() || !postScript.isEmpty() ) + { + QMap< QString, QVariant > sdetails; + sdetails.insert( "pre-script", preScript ); + sdetails.insert( "package", packageName ); + sdetails.insert( "post-script", postScript ); + return sdetails; + } + else + { + return packageName; + } +} + PackageTreeItem::PackageTreeItem( const ItemData& data, PackageTreeItem* parent ) : m_parentItem( parent ) , m_data( data ) diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index c35dc5733..c2672b4d4 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -37,6 +37,13 @@ public: bool isCritical = false; bool isHidden = false; Qt::CheckState selected = Qt::Unchecked; + + /** @brief Turns this item into a variant for PackageOperations use + * + * For "plain" items, this is just the package name; items with + * scripts return a map. See the package module for how it's interpreted. + */ + QVariant toOperation() const; }; explicit PackageTreeItem( const ItemData& data, PackageTreeItem* parent = nullptr ); explicit PackageTreeItem( const QString packageName, PackageTreeItem* parent = nullptr ); From 7cadfb8dddb3b1f2e2068024b9334917d309f90c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 12:02:16 +0100 Subject: [PATCH 55/78] [packages] Log unfamiliar package operations - unknown operations get a warning - "source" will be added from netinstall shortly --- src/modules/packages/main.py | 5 ++++- src/modules/packages/packages.conf | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/modules/packages/main.py b/src/modules/packages/main.py index aa4bb8b12..685cea0e5 100644 --- a/src/modules/packages/main.py +++ b/src/modules/packages/main.py @@ -478,7 +478,10 @@ def run_operations(pkgman, entry): else: for package in package_list: pkgman.install_package(package, from_local=True) - + elif key == "source": + libcalamares.utils.debug("Package-list from {!s}".format(entry[key])) + else: + libcalamares.utils.warning("Unknown package-operation key {!s}".format(key)) completed_packages += len(package_list) libcalamares.job.setprogress(completed_packages * 1.0 / total_packages) libcalamares.utils.debug(pretty_name()) diff --git a/src/modules/packages/packages.conf b/src/modules/packages/packages.conf index e42e8e9b8..7b631d79e 100644 --- a/src/modules/packages/packages.conf +++ b/src/modules/packages/packages.conf @@ -55,22 +55,25 @@ update_system: false # that is in this configuration file). # # Allowed package operations are: -# - install, try_install: will call the package manager to +# - *install*, *try_install*: will call the package manager to # install one or more packages. The install target will # abort the whole installation if package-installation # fails, while try_install carries on. Packages may be # listed as (localized) names, or as (localized) package-data. # See below for the description of the format. -# - localInstall: this is used to call the package manager +# - *localInstall*: this is used to call the package manager # to install a package from a path-to-a-package. This is # useful if you have a static package archive on the install media. # The *pacman* package manager is the only one to specially support # this operation (all others treat this the same as *install*). -# - remove, try_remove: will call the package manager to +# - *remove*, *try_remove*: will call the package manager to # remove one or more packages. The remove target will # abort the whole installation if package-removal fails, # while try_remove carries on. Packages may be listed as # (localized) names. +# One additional key is recognized, to help netinstall out: +# - *source*: ignored, does get logged +# Any other key is ignored, and logged as a warning. # # There are two formats for naming packages: as a name or as package-data, # which is an object notation providing package-name, as well as pre- and From 74169c166aa75904490bb948cf7c7c74b51ce2b2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 14:18:48 +0100 Subject: [PATCH 56/78] [netinstall] Mark operations with source-module - This will allow us to find the operations later, by looking for the same source-module. - While here, tidy up types --- src/modules/netinstall/NetInstallViewStep.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 53250ba13..e7648cd61 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -144,15 +144,17 @@ NetInstallViewStep::onLeave() if ( !installPackages.empty() ) { - QMap< QString, QVariant > op; + QVariantMap op; op.insert( "install", QVariant( installPackages ) ); + op.insert( "source", moduleInstanceKey().toString() ); packageOperations.append( op ); cDebug() << Logger::SubEntry << installPackages.length() << "critical packages."; } if ( !tryInstallPackages.empty() ) { - QMap< QString, QVariant > op; + QVariantMap op; op.insert( "try_install", QVariant( tryInstallPackages ) ); + op.insert( "source", moduleInstanceKey().toString() ); packageOperations.append( op ); cDebug() << Logger::SubEntry << tryInstallPackages.length() << "non-critical packages."; } From 5f1bd4396e97eaeb0ec03264cdcb871fe88015be Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 14:46:00 +0100 Subject: [PATCH 57/78] [netinstall] Avoid duplicate operations - Since operations are added each time you leave this page, the existing operations (from a previous visit) need to be cleaned up. With the old setup of only **one** possible set of operations, this wasn't a problem. Now, merging in operations is necessary. Implement that by looking for the *source* property in an operation. FIXES #1303 --- src/modules/netinstall/NetInstallViewStep.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index e7648cd61..b0fe53083 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -125,6 +125,19 @@ NetInstallViewStep::onLeave() QVariantList packageOperations = gs->contains( PACKAGEOP ) ? gs->value( PACKAGEOP ).toList() : QVariantList(); cDebug() << Logger::SubEntry << "Existing package operations length" << packageOperations.length(); + // Clear out existing operations for this module, going backwards: + // Sometimes we remove an item, and we don't want the index to + // fall off the end of the list. + for ( int index = packageOperations.length() - 1; 0 <= index ; index-- ) + { + const QVariantMap op = packageOperations.at(index).toMap(); + if ( op.contains( "source" ) && op.value( "source" ).toString() == moduleInstanceKey().toString() ) + { + cDebug() << Logger::SubEntry << "Removing existing operations for" << moduleInstanceKey(); + packageOperations.removeAt( index ); + } + } + // This netinstall module may add two sub-steps to the packageOperations, // one for installing and one for try-installing. QVariantList installPackages; From eb127a5e1b19fa47d493227e8d694ea9fb54b151 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 15:04:49 +0100 Subject: [PATCH 58/78] Changes: document netinstall module changes --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 4bc35f2d5..377aa2271 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,11 @@ This release contains contributions from (alphabetically by first name): - The *users* module now has knobs for setting the hostname and writing the `/etc/hosts` file. The new configuration options are documented in `users.conf`. #1140 + - Multiple *netinstall* modules can exist side-by-side, and they each + control the package installation for their part of the package list. + Previously, a netinstall module would overwrite all of the package + configuration done by other netinstall modules. + #1303 # 3.2.18 (2020-01-28) # From bc5aa1f8370347e2374f6b7d76a8134ed472a466 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 17:37:16 +0100 Subject: [PATCH 59/78] [netinstall] Pretend to clean up resources --- src/modules/netinstall/NetInstallPage.cpp | 8 ++++++-- src/modules/netinstall/NetInstallPage.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index c3754e1c2..2f455f2eb 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -34,8 +34,6 @@ #include #include -using CalamaresUtils::yamlToVariant; - NetInstallPage::NetInstallPage( QWidget* parent ) : QWidget( parent ) , ui( new Ui::Page_NetInst ) @@ -45,6 +43,12 @@ NetInstallPage::NetInstallPage( QWidget* parent ) ui->setupUi( this ); } +NetInstallPage::~NetInstallPage() +{ + delete m_groups; + delete m_reply; +} + bool NetInstallPage::readGroups( const QByteArray& yamlData ) { diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index fbd60a8fd..2f457387d 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -39,6 +39,7 @@ class NetInstallPage : public QWidget Q_OBJECT public: NetInstallPage( QWidget* parent = nullptr ); + virtual ~NetInstallPage(); void onActivate(); From d909b8119e1fdafa7dcdb6013fd9f39775abc923 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 17:37:58 +0100 Subject: [PATCH 60/78] [netinstall] Code-style --- src/modules/netinstall/NetInstallViewStep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index b0fe53083..5f64b95d3 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -128,9 +128,9 @@ NetInstallViewStep::onLeave() // Clear out existing operations for this module, going backwards: // Sometimes we remove an item, and we don't want the index to // fall off the end of the list. - for ( int index = packageOperations.length() - 1; 0 <= index ; index-- ) + for ( int index = packageOperations.length() - 1; 0 <= index; index-- ) { - const QVariantMap op = packageOperations.at(index).toMap(); + const QVariantMap op = packageOperations.at( index ).toMap(); if ( op.contains( "source" ) && op.value( "source" ).toString() == moduleInstanceKey().toString() ) { cDebug() << Logger::SubEntry << "Removing existing operations for" << moduleInstanceKey(); From 0877a994f1d08d998327337b72492e4d82510bd0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 17:40:15 +0100 Subject: [PATCH 61/78] [netinstall] Update copyright --- src/modules/netinstall/NetInstallPage.cpp | 2 +- src/modules/netinstall/NetInstallPage.h | 2 +- src/modules/netinstall/NetInstallViewStep.cpp | 2 +- src/modules/netinstall/PackageTreeItem.cpp | 2 +- src/modules/netinstall/PackageTreeItem.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 2f455f2eb..620e37225 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -2,7 +2,7 @@ * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo * Copyright 2017, Kyle Robbertze - * Copyright 2017-2018, Adriaan de Groot + * Copyright 2017-2018, 2020, Adriaan de Groot * Copyright 2017, Gabriel Craciunescu * * Calamares is free software: you can redistribute it and/or modify diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index 2f457387d..78eae85a8 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -2,7 +2,7 @@ * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo * Copyright 2017, Kyle Robbertze - * Copyright 2017-2018, Adriaan de Groot + * Copyright 2017-2018, 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 diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 5f64b95d3..948899eb9 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -2,7 +2,7 @@ * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo * Copyright 2017, Kyle Robbertze - * Copyright 2017-2018, Adriaan de Groot + * Copyright 2017-2018, 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 diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index bbd85975e..a1744df39 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright (c) 2017, Kyle Robbertze - * Copyright 2017, Adriaan de Groot + * Copyright 2017, 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 diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index c2672b4d4..d30f57622 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright (c) 2017, Kyle Robbertze - * Copyright 2017, Adriaan de Groot + * Copyright 2017, 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 From 4ae484dbca835f31459fe32c1dfb901ea15e8dad Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 17:46:56 +0100 Subject: [PATCH 62/78] [netinstall] Initial work for configurable sidebar label - Now that multiple netinstall pages may be supported, it's annoying that they all have the same name. Copy the approach from other modules (e.g. notesQML) of having the sidebar and other labels configured in the config file. --- src/modules/netinstall/NetInstallViewStep.cpp | 4 +++- src/modules/netinstall/NetInstallViewStep.h | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 948899eb9..92947bbfd 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -34,6 +34,7 @@ NetInstallViewStep::NetInstallViewStep( QObject* parent ) : Calamares::ViewStep( parent ) , m_widget( new NetInstallPage() ) , m_nextEnabled( false ) + , m_sidebarLabel( nullptr ) { emit nextStatusChanged( true ); connect( m_widget, &NetInstallPage::checkReady, this, &NetInstallViewStep::nextIsReady ); @@ -46,13 +47,14 @@ NetInstallViewStep::~NetInstallViewStep() { m_widget->deleteLater(); } + delete m_sidebarLabel; } QString NetInstallViewStep::prettyName() const { - return tr( "Package selection" ); + return m_sidebarLabel ? m_sidebarLabel->get() : tr( "Package selection" ); } diff --git a/src/modules/netinstall/NetInstallViewStep.h b/src/modules/netinstall/NetInstallViewStep.h index be92f5cc3..c6beab6bf 100644 --- a/src/modules/netinstall/NetInstallViewStep.h +++ b/src/modules/netinstall/NetInstallViewStep.h @@ -20,10 +20,10 @@ #ifndef NETINSTALLVIEWSTEP_H #define NETINSTALLVIEWSTEP_H -#include -#include - -#include +#include "DllMacro.h" +#include "locale/TranslatableConfiguration.h" +#include "utils/PluginFactory.h" +#include "viewpages/ViewStep.h" #include @@ -64,7 +64,7 @@ private: NetInstallPage* m_widget; bool m_nextEnabled; QString m_prettyStatus; - + CalamaresUtils::Locale::TranslatedString* m_sidebarLabel; // As it appears in the sidebar QList< Calamares::job_ptr > m_jobs; }; From be567dc50848e21bfe23dbd03d1e2957ee75f7ec Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 17:50:39 +0100 Subject: [PATCH 63/78] [netinstall] Remove unused m_prettyStatus --- src/modules/netinstall/NetInstallViewStep.cpp | 7 ------- src/modules/netinstall/NetInstallViewStep.h | 2 -- 2 files changed, 9 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 92947bbfd..6456e6f96 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -58,13 +58,6 @@ NetInstallViewStep::prettyName() const } -QString -NetInstallViewStep::prettyStatus() const -{ - return m_prettyStatus; -} - - QWidget* NetInstallViewStep::widget() { diff --git a/src/modules/netinstall/NetInstallViewStep.h b/src/modules/netinstall/NetInstallViewStep.h index c6beab6bf..ad796b8b2 100644 --- a/src/modules/netinstall/NetInstallViewStep.h +++ b/src/modules/netinstall/NetInstallViewStep.h @@ -38,7 +38,6 @@ public: virtual ~NetInstallViewStep() override; QString prettyName() const override; - QString prettyStatus() const override; QWidget* widget() override; @@ -63,7 +62,6 @@ public slots: private: NetInstallPage* m_widget; bool m_nextEnabled; - QString m_prettyStatus; CalamaresUtils::Locale::TranslatedString* m_sidebarLabel; // As it appears in the sidebar QList< Calamares::job_ptr > m_jobs; }; From 45c15de623cd7c7adf76d5884e3f9071f99cb8d4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 17:59:34 +0100 Subject: [PATCH 64/78] [netinstall] Configurable name in the sidebar --- src/modules/netinstall/NetInstallViewStep.cpp | 23 ++++++++++++++----- src/modules/netinstall/netinstall.conf | 14 +++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 6456e6f96..178862aa7 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -173,6 +173,12 @@ NetInstallViewStep::onLeave() } } +void +NetInstallViewStep::nextIsReady( bool b ) +{ + m_nextEnabled = b; + emit nextStatusChanged( b ); +} void NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap ) @@ -187,11 +193,16 @@ NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap ) Calamares::JobQueue::instance()->globalStorage()->insert( "groupsUrl", groupsUrl ); m_widget->loadGroupList( groupsUrl ); } -} -void -NetInstallViewStep::nextIsReady( bool b ) -{ - m_nextEnabled = b; - emit nextStatusChanged( b ); + bool bogus = false; + auto label = CalamaresUtils::getSubMap( configurationMap, "label", bogus ); + + if ( label.contains( "sidebar" ) ) + { + m_sidebarLabel = new CalamaresUtils::Locale::TranslatedString( label, "sidebar" ); + } + if ( label.contains( "title" ) ) + { + // Set that label on the page + } } diff --git a/src/modules/netinstall/netinstall.conf b/src/modules/netinstall/netinstall.conf index fd59c24c6..ab600326e 100644 --- a/src/modules/netinstall/netinstall.conf +++ b/src/modules/netinstall/netinstall.conf @@ -21,3 +21,17 @@ # This only has an effect if the netinstall data cannot be retrieved, # or is corrupt: having "required" set, means the install cannot proceed. required: false + +# To support multiple instances of this module, +# some strings are configurable and translatable here. +# - *sidebar* This is the name of the module in the progress-tree / sidebar +# in Calamares. +# - *title* This is displayed above the list of packages. +# If no *sidebar* values are provided, defaults to "Package selection" +# and existing translations. If no *title* values are provided, no string +# is displayed. +label: + sidebar: "Package selection" + sidebar[nl]: "Pakketkeuze" + title: "Office Package" + title[nl]: "Kantoorsoftware" From 497ecda14dc627d8d0f81b5d3c7b2169431dd218 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Feb 2020 23:17:18 +0100 Subject: [PATCH 65/78] [netinstall] Move translation of widget headers Editorial: I really don't like plain CALAMARES_RETRANSLATE() thrown into the middle of code. --- src/modules/netinstall/NetInstallPage.cpp | 14 ++++++++++++-- src/modules/netinstall/NetInstallPage.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 620e37225..33c8b0d01 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -41,6 +41,7 @@ NetInstallPage::NetInstallPage( QWidget* parent ) , m_groups( nullptr ) { ui->setupUi( this ); + CALAMARES_RETRANSLATE_SLOT( &NetInstallPage::retranslate ); } NetInstallPage::~NetInstallPage() @@ -49,6 +50,16 @@ NetInstallPage::~NetInstallPage() delete m_reply; } +void +NetInstallPage::retranslate() +{ + if ( m_groups ) + { + m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); + m_groups->setHeaderData( 1, Qt::Horizontal, tr( "Description" ) ); + } +} + bool NetInstallPage::readGroups( const QByteArray& yamlData ) { @@ -62,8 +73,6 @@ NetInstallPage::readGroups( const QByteArray& yamlData ) } Q_ASSERT( groups.IsSequence() ); m_groups = new PackageModel( groups ); - CALAMARES_RETRANSLATE( m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); - m_groups->setHeaderData( 1, Qt::Horizontal, tr( "Description" ) ); ) return true; } catch ( YAML::Exception& e ) @@ -125,6 +134,7 @@ NetInstallPage::dataIsHere() return; } + retranslate(); // For changed model ui->groupswidget->setModel( m_groups ); ui->groupswidget->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); ui->groupswidget->header()->setSectionResizeMode( 1, QHeaderView::Stretch ); diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index 78eae85a8..cacb24e49 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -64,6 +64,8 @@ public: public slots: void dataIsHere(); + void retranslate(); + signals: void checkReady( bool ); From 5b67ca315a4f8ba063b4b8288c5dda3836077256 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 01:24:24 +0100 Subject: [PATCH 66/78] [netinstall] It should be easier to get the number 2 --- src/modules/netinstall/PackageModel.cpp | 6 +----- src/modules/netinstall/PackageTreeItem.cpp | 6 ------ src/modules/netinstall/PackageTreeItem.h | 2 -- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index b5b256ae0..f7222194d 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -106,11 +106,7 @@ PackageModel::rowCount( const QModelIndex& parent ) const int PackageModel::columnCount( const QModelIndex& parent ) const { - if ( parent.isValid() ) - { - return static_cast< PackageTreeItem* >( parent.internalPointer() )->columnCount(); - } - return m_rootItem->columnCount(); + return 2; } QVariant diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index a1744df39..59e82a659 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -105,12 +105,6 @@ PackageTreeItem::row() const return 0; } -int -PackageTreeItem::columnCount() const -{ - return m_columns; -} - QVariant PackageTreeItem::data( int column ) const { diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index d30f57622..18a509861 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -54,7 +54,6 @@ public: void appendChild( PackageTreeItem* child ); PackageTreeItem* child( int row ); int childCount() const; - int columnCount() const; QVariant data( int column ) const override; int row() const; @@ -90,7 +89,6 @@ private: PackageTreeItem* m_parentItem; QList< PackageTreeItem* > m_childItems; ItemData m_data; - const int m_columns = 2; // Name, description }; #endif // PACKAGETREEITEM_H From f6d8ed85e4521bff8e77c22be1b9e1eb868be72a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 09:29:23 +0100 Subject: [PATCH 67/78] [netinstall] Allow a title above the netinstall tree - Supports translation via the config file. This is useful (like label:sidebar) when displaying more than one netinstall page. --- src/modules/netinstall/NetInstallPage.cpp | 21 +++++++++++++++++++ src/modules/netinstall/NetInstallPage.h | 17 +++++++++++++++ src/modules/netinstall/NetInstallViewStep.cpp | 2 +- src/modules/netinstall/page_netinst.ui | 12 ++++++++++- 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 33c8b0d01..c30dbb4da 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -41,6 +41,7 @@ NetInstallPage::NetInstallPage( QWidget* parent ) , m_groups( nullptr ) { ui->setupUi( this ); + setPageTitle( nullptr ); CALAMARES_RETRANSLATE_SLOT( &NetInstallPage::retranslate ); } @@ -50,6 +51,22 @@ NetInstallPage::~NetInstallPage() delete m_reply; } +void +NetInstallPage::setPageTitle( CalamaresUtils::Locale::TranslatedString* t ) +{ + m_title.reset( t ); + if ( !m_title ) + { + ui->label->hide(); + } + else + { + ui->label->show(); + } + retranslate(); +} + + void NetInstallPage::retranslate() { @@ -58,6 +75,10 @@ NetInstallPage::retranslate() m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); m_groups->setHeaderData( 1, Qt::Horizontal, tr( "Description" ) ); } + if ( ui && m_title ) + { + ui->label->setText( m_title->get() ); // That's get() on the TranslatedString + } } bool diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index cacb24e49..12633c6b9 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -24,9 +24,13 @@ #include "PackageModel.h" #include "PackageTreeItem.h" +#include "locale/TranslatableConfiguration.h" + #include #include +#include + class QNetworkReply; namespace Ui @@ -41,6 +45,17 @@ public: NetInstallPage( QWidget* parent = nullptr ); virtual ~NetInstallPage(); + /** @brief Sets the page title + * + * In situations where there is more than one netinstall page, + * or you want some explanatory title above the treeview, + * set the page title. This page takes ownership of the + * TranslatedString object. + * + * Set to nullptr to remove the title. + */ + void setPageTitle( CalamaresUtils::Locale::TranslatedString* ); + void onActivate(); /** @brief Retrieves the groups, with name, description and packages @@ -77,6 +92,8 @@ private: Ui::Page_NetInst* ui; + std::unique_ptr< CalamaresUtils::Locale::TranslatedString > m_title; // Above the treeview + QNetworkReply* m_reply; PackageModel* m_groups; bool m_required; diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 178862aa7..3227ecd65 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -203,6 +203,6 @@ NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } if ( label.contains( "title" ) ) { - // Set that label on the page + m_widget->setPageTitle( new CalamaresUtils::Locale::TranslatedString( label, "title" ) ); } } diff --git a/src/modules/netinstall/page_netinst.ui b/src/modules/netinstall/page_netinst.ui index 3aa4e57ec..917057ff4 100644 --- a/src/modules/netinstall/page_netinst.ui +++ b/src/modules/netinstall/page_netinst.ui @@ -14,6 +14,16 @@ + + + + Title of Netinstall Module + + + Qt::AlignCenter + + + @@ -31,7 +41,7 @@ 0 0 981 - 434 + 407 From da66ef42d708e571dc895150d9dcc68e3ae612ec Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 12:36:12 +0100 Subject: [PATCH 68/78] Changes: document a little more netinstall --- CHANGES | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 377aa2271..0ecaafb51 100644 --- a/CHANGES +++ b/CHANGES @@ -37,8 +37,8 @@ This release contains contributions from (alphabetically by first name): - Multiple *netinstall* modules can exist side-by-side, and they each control the package installation for their part of the package list. Previously, a netinstall module would overwrite all of the package - configuration done by other netinstall modules. - #1303 + configuration done by other netinstall modules. Translations can be + provided in the configuration file, `netinstall.conf`. #1303 # 3.2.18 (2020-01-28) # From c20f7ee5349165a0edc437be4401281e3c3f40a0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 12:51:01 +0100 Subject: [PATCH 69/78] [netinstall] Rip out derpy translations of PackageModel - The model always has two columns, and the column names are always the same. We don't need to specially set headers for that. - Use QCoreApplication::translation() to re-use the existing translations and avoid creating "new" strings (in a new context). --- src/modules/netinstall/NetInstallPage.cpp | 6 ----- src/modules/netinstall/PackageModel.cpp | 31 +++++++---------------- src/modules/netinstall/PackageModel.h | 8 +++--- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index c30dbb4da..735610c3d 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -66,15 +66,9 @@ NetInstallPage::setPageTitle( CalamaresUtils::Locale::TranslatedString* t ) retranslate(); } - void NetInstallPage::retranslate() { - if ( m_groups ) - { - m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); - m_groups->setHeaderData( 1, Qt::Horizontal, tr( "Description" ) ); - } if ( ui && m_title ) { ui->label->setText( m_title->get() ); // That's get() on the TranslatedString diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index f7222194d..6d299f633 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -21,9 +21,11 @@ #include "utils/Yaml.h" +// TODO: see headerData(), remove after 3.2.19 +#include + PackageModel::PackageModel( const YAML::Node& data, QObject* parent ) : QAbstractItemModel( parent ) - , m_columnHeadings() { m_rootItem = new PackageTreeItem(); setupModelData( data, m_rootItem ); @@ -150,26 +152,6 @@ PackageModel::setData( const QModelIndex& index, const QVariant& value, int role return true; } -bool -PackageModel::setHeaderData( int section, Qt::Orientation orientation, const QVariant& value, int role ) -{ - Q_UNUSED( role ) - - if ( orientation == Qt::Horizontal ) - { - if ( m_columnHeadings.value( section ) != QVariant() ) - { - m_columnHeadings.replace( section, value ); - } - else - { - m_columnHeadings.insert( section, value ); - } - emit headerDataChanged( orientation, section, section ); - } - return true; -} - Qt::ItemFlags PackageModel::flags( const QModelIndex& index ) const { @@ -189,7 +171,12 @@ PackageModel::headerData( int section, Qt::Orientation orientation, int role ) c { if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) { - return m_columnHeadings.value( section ); + // Unusual translation call uses the existing translation from the NetInstallPage + // class (now removed). + // + // TODO: after 3.2.19, change this to just tr() and push TX + return ( section == 0 ) ? QCoreApplication::translate( "NetInstallPage", "Name" ) + : QCoreApplication::translate( "NetInstallPage", "Description" ); } return QVariant(); } diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index cd8f676c8..25965cb7f 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -44,14 +44,15 @@ public: QVariant data( const QModelIndex& index, int role ) const override; bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) override; - bool - setHeaderData( int section, Qt::Orientation orientation, const QVariant& value, int role = Qt::EditRole ) override; Qt::ItemFlags flags( const QModelIndex& index ) const override; - QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; + QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const override; QModelIndex parent( const QModelIndex& index ) const override; + + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; int rowCount( const QModelIndex& parent = QModelIndex() ) const override; int columnCount( const QModelIndex& parent = QModelIndex() ) const override; + PackageItemDataList getPackages() const; QList< PackageTreeItem* > getItemPackages( PackageTreeItem* item ) const; @@ -60,7 +61,6 @@ private: PackageTreeItem* m_rootItem; QList< PackageTreeItem* > m_hiddenItems; - QVariantList m_columnHeadings; }; #endif // PACKAGEMODEL_H From 25e3f917540b9271484094d16b078aaeffacd172 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 13:39:24 +0100 Subject: [PATCH 70/78] [welcome] Remove the QML testing bits - The welcomeq module has actual QML support --- src/modules/welcome/CMakeLists.txt | 10 ---- src/modules/welcome/Config.cpp | 28 ---------- src/modules/welcome/Config.h | 40 -------------- src/modules/welcome/qmlmain.cpp | 84 ------------------------------ src/modules/welcome/welcome.qml | 29 ----------- 5 files changed, 191 deletions(-) delete mode 100644 src/modules/welcome/Config.cpp delete mode 100644 src/modules/welcome/Config.h delete mode 100644 src/modules/welcome/qmlmain.cpp delete mode 100644 src/modules/welcome/welcome.qml diff --git a/src/modules/welcome/CMakeLists.txt b/src/modules/welcome/CMakeLists.txt index b25bb6720..e25b7f5d0 100644 --- a/src/modules/welcome/CMakeLists.txt +++ b/src/modules/welcome/CMakeLists.txt @@ -40,13 +40,3 @@ calamares_add_plugin( welcome Qt5::Network SHARED_LIB ) - -add_executable( welcomeqmltest qmlmain.cpp Config.cpp ) -target_link_libraries( welcomeqmltest PRIVATE calamaresui Qt5::Core ) -set_target_properties( welcomeqmltest - PROPERTIES - ENABLE_EXPORTS TRUE - RUNTIME_OUTPUT_NAME welcomeqmltest -) -calamares_automoc( welcomeqmltest ) -calamares_autouic( welcomeqmltest ) diff --git a/src/modules/welcome/Config.cpp b/src/modules/welcome/Config.cpp deleted file mode 100644 index b46b85bf3..000000000 --- a/src/modules/welcome/Config.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2019, 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 "Config.h" - -Config::Config() - : m_helpUrl( "https://www.kde.org/" ) -{ -} - -Config::~Config() -{ -} diff --git a/src/modules/welcome/Config.h b/src/modules/welcome/Config.h deleted file mode 100644 index 7b0cfd734..000000000 --- a/src/modules/welcome/Config.h +++ /dev/null @@ -1,40 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2019, 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 WELCOME_CONFIG_H -#define WELCOME_CONFIG_H - -#include -#include - -class Config : public QObject -{ - Q_OBJECT - Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl CONSTANT ) -public: - Config(); - virtual ~Config(); - - QUrl helpUrl() const { return m_helpUrl; } - void setHelpUrl( const QUrl& url ) { m_helpUrl = url; } - -private: - QUrl m_helpUrl; -}; - -#endif diff --git a/src/modules/welcome/qmlmain.cpp b/src/modules/welcome/qmlmain.cpp deleted file mode 100644 index a9dd1875d..000000000 --- a/src/modules/welcome/qmlmain.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* Example executable showing a QML page and using the - * models from libcalamares for displaying a welcome. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "Branding.h" -#include "JobQueue.h" -#include "Settings.h" -#include "locale/LabelModel.h" -#include "utils/Logger.h" - -#include "Config.h" - -static Config* theConfig() -{ - static Config* cnf = new Config(); - return cnf; -} - -int main(int argc, char **argv) -{ - QApplication a( argc, argv ); - - KAboutData aboutData( "calamares", - "Calamares", - "0.1", - "Calamares QML Test Application", - KAboutLicense::GPL_V3, - QString(), - QString(), - "https://calamares.io", - "https://github.com/calamares/calamares/issues" ); - KAboutData::setApplicationData( aboutData ); - a.setApplicationDisplayName( QString() ); // To avoid putting an extra "Calamares/" into the log-file - - Logger::setupLogLevel( Logger::LOGVERBOSE ); - - std::unique_ptr< Calamares::Settings > settings_p( Calamares::Settings::init( QString() ) ); - std::unique_ptr< Calamares::JobQueue > jobqueue_p( new Calamares::JobQueue( nullptr ) ); - - Calamares::Branding defaultBrand( "src/branding/default/branding.desc" ); - cDebug() << "Branding @" << (void *)Calamares::Branding::instance(); - - QMainWindow mw; - QWidget background; - QVBoxLayout vl; - QLabel l( "Hello, world", &mw ); - QQuickWidget qqw( &mw ); - vl.addWidget( &qqw ); - vl.addWidget( &l ); - background.setLayout( &vl ); - mw.setCentralWidget( &background ); - mw.resize( QSize( 400, 400 ) ); - mw.show(); - - Config cnf; - if ( argc > 1 ) - { - cnf.setHelpUrl( QUrl( argv[1] ) ); - } - - // TODO: this should put the one config object in the context, rather than adding a factory function to share it everywhere - qmlRegisterSingletonType< Config >( "io.calamares.modules.welcome", 1, 0, "PotatoConfig", [](QQmlEngine*, QJSEngine*) -> QObject* { return theConfig(); }); - - qmlRegisterSingletonType< CalamaresUtils::Locale::LabelModel >( "io.calamares.locale", 1, 0, "LocaleModel", [](QQmlEngine*, QJSEngine*) -> QObject* { return CalamaresUtils::Locale::availableTranslations(); } ); - - qqw.setSource( QUrl::fromLocalFile("../src/modules/welcome/welcome.qml") ); - - return a.exec(); -} diff --git a/src/modules/welcome/welcome.qml b/src/modules/welcome/welcome.qml deleted file mode 100644 index bdb7c4416..000000000 --- a/src/modules/welcome/welcome.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0; -import QtQuick.Controls 2.3; -import io.calamares.modules.welcome 1.0; -import io.calamares.locale 1.0; - -Rectangle { - width: 200; - height: 200; - color: "pink"; - - Label { - id: label; - anchors.centerIn: parent; - text: "Welcome to Calamares"; - } - - Button { - id: thebutton; - anchors.top: label.bottom; - text: PotatoConfig.helpUrl; - - } - - ListView { - anchors.fill: parent; - model: LocaleModel; - delegate: Label { text: display } - } -} From 0ef28f6a50aa5e9d4886968f688ec6edd35930e3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 14:02:04 +0100 Subject: [PATCH 71/78] [libcalamares] Translatable config strings use tr()-infrastructure - Allow TranslatedString to get a context parameter; if it has one, it will try to use the regular tr()-infrastructure **as fallback** for the translations from the config file itself. - This makes it possible to offer -- and translate -- some "standard" phrases in the module, while allowing the config file the knob to change strings. Using one of the standard strings gets translations for "free", while introducing something entirely new means sourcing translations for it as well. --- .../locale/TranslatableConfiguration.cpp | 17 +++++++++++++++-- .../locale/TranslatableConfiguration.h | 3 ++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/libcalamares/locale/TranslatableConfiguration.cpp b/src/libcalamares/locale/TranslatableConfiguration.cpp index bc39c398e..83199a4cc 100644 --- a/src/libcalamares/locale/TranslatableConfiguration.cpp +++ b/src/libcalamares/locale/TranslatableConfiguration.cpp @@ -23,6 +23,7 @@ #include "utils/Logger.h" #include "utils/Variant.h" +#include #include #include @@ -34,7 +35,9 @@ TranslatedString::TranslatedString( const QString& string ) { m_strings[ QString() ] = string; } -TranslatedString::TranslatedString( const QVariantMap& map, const QString& key ) + +TranslatedString::TranslatedString( const QVariantMap& map, const QString& key, const char* context ) + : m_context( context ) { // Get the un-decorated value for the key QString value = CalamaresUtils::getString( map, key ); @@ -99,7 +102,17 @@ TranslatedString::get( const QLocale& locale ) const } } - return m_strings[ QString() ]; + // If we're given a context to work with, also try the same string in + // the regular translation framework. + const QString& s = m_strings[ QString() ]; + if ( m_context ) + { + return QCoreApplication::translate( m_context, s.toLatin1().constData() ); + } + else + { + return s; + } } diff --git a/src/libcalamares/locale/TranslatableConfiguration.h b/src/libcalamares/locale/TranslatableConfiguration.h index 45679bce0..f1abb51ff 100644 --- a/src/libcalamares/locale/TranslatableConfiguration.h +++ b/src/libcalamares/locale/TranslatableConfiguration.h @@ -40,7 +40,7 @@ class DLLEXPORT TranslatedString public: /** @brief Get all the translations connected to @p key */ - TranslatedString( const QVariantMap& map, const QString& key ); + TranslatedString( const QVariantMap& map, const QString& key, const char* context = nullptr ); /** @brief Not-actually-translated string. */ TranslatedString( const QString& string ); @@ -73,6 +73,7 @@ public: private: // Maps locale name to human-readable string, "" is English QMap< QString, QString > m_strings; + const char* m_context = nullptr; }; } // namespace Locale } // namespace CalamaresUtils From a03394f177e3509ff0d4acf884b288c1aa770436 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 14:09:04 +0100 Subject: [PATCH 72/78] [netinstall] Use tr() infrastructure for config-translations --- src/modules/netinstall/NetInstallViewStep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 3227ecd65..6c26061a7 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -199,10 +199,10 @@ NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap ) if ( label.contains( "sidebar" ) ) { - m_sidebarLabel = new CalamaresUtils::Locale::TranslatedString( label, "sidebar" ); + m_sidebarLabel = new CalamaresUtils::Locale::TranslatedString( label, "sidebar", metaObject()->className() ); } if ( label.contains( "title" ) ) { - m_widget->setPageTitle( new CalamaresUtils::Locale::TranslatedString( label, "title" ) ); + m_widget->setPageTitle( new CalamaresUtils::Locale::TranslatedString( label, "title", metaObject()->className() ) ); } } From 81752b6f7c927b902a76d791c3e179320dd31492 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 14:23:34 +0100 Subject: [PATCH 73/78] [libcalamares] Document how TranslatedString context works - Support re-using class-specific tr() calls in a standard way - Document this in the netinstall.conf which uses it --- src/libcalamares/locale/TranslatableConfiguration.h | 11 +++++++++++ src/modules/netinstall/netinstall.conf | 12 +++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/libcalamares/locale/TranslatableConfiguration.h b/src/libcalamares/locale/TranslatableConfiguration.h index f1abb51ff..d845569bc 100644 --- a/src/libcalamares/locale/TranslatableConfiguration.h +++ b/src/libcalamares/locale/TranslatableConfiguration.h @@ -39,6 +39,17 @@ class DLLEXPORT TranslatedString { public: /** @brief Get all the translations connected to @p key + * + * Gets map[key] as the "untranslated" form, and then all the + * keys of the form [lang] are taken as the translation + * for of the untranslated form. + * + * If @p context is not a nullptr, then that is taken as an + * indication to **also** use the regular QObject::tr() translation + * mechanism for these strings. It is recommended to pass in + * metaObject()->className() as context (from a QObject based class) + * to give the TranslatedString the same context as other calls + * to tr() within that class. */ TranslatedString( const QVariantMap& map, const QString& key, const char* context = nullptr ); /** @brief Not-actually-translated string. diff --git a/src/modules/netinstall/netinstall.conf b/src/modules/netinstall/netinstall.conf index ab600326e..188642683 100644 --- a/src/modules/netinstall/netinstall.conf +++ b/src/modules/netinstall/netinstall.conf @@ -30,8 +30,14 @@ required: false # If no *sidebar* values are provided, defaults to "Package selection" # and existing translations. If no *title* values are provided, no string # is displayed. +# +# The following strings are already known to Calamares and can be +# listed here in *untranslated* form (e.g. as value of *sidebar*) +# without bothering with the translations: they are picked up from +# the regular translation framework: +# - "Package selection" label: sidebar: "Package selection" - sidebar[nl]: "Pakketkeuze" - title: "Office Package" - title[nl]: "Kantoorsoftware" + # sidebar[nl]: "Pakketkeuze" + # title: "Office Package" + # title[nl]: "Kantoorsoftware" From 538779991ed4c4066a428f0a3b444fa04a95b64e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 14:37:47 +0100 Subject: [PATCH 74/78] [netinstall] Add some "standard" sidebar labels for the module --- src/modules/netinstall/NetInstallViewStep.cpp | 14 +++++++++++++- src/modules/netinstall/netinstall.conf | 5 +++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 6c26061a7..8de3fd74f 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -55,6 +55,17 @@ QString NetInstallViewStep::prettyName() const { return m_sidebarLabel ? m_sidebarLabel->get() : tr( "Package selection" ); + + // This is a table of "standard" labels for this module. If you use them + // in the label: sidebar: section of the config file, the existing + // translations can be used. + NOTREACHED + tr( "Package selection" ); + tr( "Office software" ); + tr( "Office package" ); + tr( "Browser software" ); + tr( "Browser package" ); + tr( "Web browser" ); } @@ -203,6 +214,7 @@ NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } if ( label.contains( "title" ) ) { - m_widget->setPageTitle( new CalamaresUtils::Locale::TranslatedString( label, "title", metaObject()->className() ) ); + m_widget->setPageTitle( + new CalamaresUtils::Locale::TranslatedString( label, "title", metaObject()->className() ) ); } } diff --git a/src/modules/netinstall/netinstall.conf b/src/modules/netinstall/netinstall.conf index 188642683..5f90fec76 100644 --- a/src/modules/netinstall/netinstall.conf +++ b/src/modules/netinstall/netinstall.conf @@ -36,6 +36,11 @@ required: false # without bothering with the translations: they are picked up from # the regular translation framework: # - "Package selection" +# - "Office software" +# - "Office package" +# - "Browser software" +# - "Browser package" +# - "Web browser" label: sidebar: "Package selection" # sidebar[nl]: "Pakketkeuze" From 51ad7df31c1f9ab28ae48de0a6d9be4d07c66ef0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 17:13:01 +0100 Subject: [PATCH 75/78] [netinstall] Don't give the translators a bogus string --- src/modules/netinstall/page_netinst.ui | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/modules/netinstall/page_netinst.ui b/src/modules/netinstall/page_netinst.ui index 917057ff4..32c11ec15 100644 --- a/src/modules/netinstall/page_netinst.ui +++ b/src/modules/netinstall/page_netinst.ui @@ -16,9 +16,6 @@ - - Title of Netinstall Module - Qt::AlignCenter From 2d754dac6db66e5559c2a7a2ba44e85bbd096eb8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 17:15:40 +0100 Subject: [PATCH 76/78] [notesqml] Rename example file to save translators --- .../{dummyqml.qml => notesqml.qml.example} | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) rename src/modules/notesqml/examples/{dummyqml.qml => notesqml.qml.example} (75%) diff --git a/src/modules/notesqml/examples/dummyqml.qml b/src/modules/notesqml/examples/notesqml.qml.example similarity index 75% rename from src/modules/notesqml/examples/dummyqml.qml rename to src/modules/notesqml/examples/notesqml.qml.example index 3cbfa65fc..a41fa98fd 100644 --- a/src/modules/notesqml/examples/dummyqml.qml +++ b/src/modules/notesqml/examples/notesqml.qml.example @@ -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,14 @@ * along with Calamares. If not, see . */ +/* Some Calamares internals are available to all QML modules. + * They live in the calamares.ui namespace (filled programmatically + * by Calamares). One of the internals that is exposed is the + * Branding object, which can be used to retrieve strings and paths + * and colors. + */ +import calamares.ui 1.0 + import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Window 2.2 @@ -30,8 +39,9 @@ Item { id: flick anchors.fill: parent contentHeight: 800 - + ScrollBar.vertical: ScrollBar { + id: fscrollbar width: 10 policy: ScrollBar.AlwaysOn } @@ -40,33 +50,34 @@ Item { id: intro x: 1 y: 0 - width: 720 + width: parent.width - fscrollbar.width font.pointSize: 14 textFormat: Text.RichText antialiasing: true activeFocusOnPress: false wrapMode: Text.WordWrap - text: qsTr("

Generic GNU/Linux 2017.8 LTS Soapy Sousaphone

+ text: qsTr("

%1

This an example QML file, showing options in RichText with Flickable content.

- +

QML with RichText can use HTML tags, Flickable content is useful for touchscreens.

- +

This is bold text

This is italic text

This is underlined text

-

This is strikethrough

- +

This text will be center-aligned.

+

This is strikethrough

+

Code example: ls -l /home

- +

Lists:

  • Intel CPU systems
  • AMD CPU systems
- -

The vertical scrollbar is adjustable, current width set to 10.

") + +

The vertical scrollbar is adjustable, current width set to 10.

").arg(Branding.string(Branding.VersionedName)) } } From 5dac67b7100a1f84853df6e7145baaec5f4c2bc5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 17:16:51 +0100 Subject: [PATCH 77/78] [notesqml] Cut down the example text to be translated. --- src/modules/notesqml/notesqml.qml | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/modules/notesqml/notesqml.qml b/src/modules/notesqml/notesqml.qml index a41fa98fd..cb659debc 100644 --- a/src/modules/notesqml/notesqml.qml +++ b/src/modules/notesqml/notesqml.qml @@ -58,26 +58,8 @@ Item { wrapMode: Text.WordWrap text: qsTr("

%1

-

This an example QML file, showing options in RichText with Flickable content.

- -

QML with RichText can use HTML tags, Flickable content is useful for touchscreens.

- -

This is bold text

-

This is italic text

-

This is underlined text

-

This text will be center-aligned.

-

This is strikethrough

- -

Code example: - ls -l /home

- -

Lists:

-
    -
  • Intel CPU systems
  • -
  • AMD CPU systems
  • -
- -

The vertical scrollbar is adjustable, current width set to 10.

").arg(Branding.string(Branding.VersionedName)) +

These are example release notes.

" + ).arg(Branding.string(Branding.VersionedName)) } } From 7cbc43616efcc15c4ad60e37be76336404a1c449 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 19 Feb 2020 17:21:12 +0100 Subject: [PATCH 78/78] [netinstall] Some more "standard" alternative labels - Hide the labels from the compiler to avoid warnings - Add some more labels proposed by ArcoLinux --- src/modules/netinstall/NetInstallViewStep.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 8de3fd74f..cb79982f9 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -56,16 +56,23 @@ NetInstallViewStep::prettyName() const { return m_sidebarLabel ? m_sidebarLabel->get() : tr( "Package selection" ); +#if defined(TABLE_OF_TRANSLATIONS) + NOTREACHED // This is a table of "standard" labels for this module. If you use them // in the label: sidebar: section of the config file, the existing // translations can be used. - NOTREACHED tr( "Package selection" ); tr( "Office software" ); tr( "Office package" ); tr( "Browser software" ); tr( "Browser package" ); tr( "Web browser" ); + tr( "Kernel" ); + tr( "Services" ); + tr( "Login" ); + tr( "Desktop" ); + tr( "Applications" ); +#endif }