Merge branch 'fix-pckq' into calamares

This commit is contained in:
Adriaan de Groot 2021-09-06 11:27:09 +02:00
commit 42bc197f67
15 changed files with 166 additions and 97 deletions

View File

@ -95,15 +95,24 @@ Config::introductionPackage() const
return *defaultIntroduction; return *defaultIntroduction;
} }
static inline QString
make_gs_key( const Calamares::ModuleSystem::InstanceKey& key )
{
return QStringLiteral( "packagechooser_" ) + key.id();
}
void void
Config::updateGlobalStorage( const QStringList& selected ) const Config::updateGlobalStorage( const QStringList& selected ) const
{ {
if ( m_packageChoice.has_value() )
{
cWarning() << "Inconsistent package choices -- both model and single-selection QML";
}
if ( m_method == PackageChooserMethod::Legacy ) if ( m_method == PackageChooserMethod::Legacy )
{ {
//QString value = selected.join( ',' ); QString value = selected.join( ',' );
QString value = ( m_pkgc ); Calamares::JobQueue::instance()->globalStorage()->insert( make_gs_key( m_defaultId ), value );
Calamares::JobQueue::instance()->globalStorage()->insert( m_id, value ); cDebug() << m_defaultId << "selected" << value;
cDebug() << m_id<< "selected" << value;
} }
else if ( m_method == PackageChooserMethod::Packages ) else if ( m_method == PackageChooserMethod::Packages )
{ {
@ -119,16 +128,53 @@ Config::updateGlobalStorage( const QStringList& selected ) const
} }
void void
Config::setPkgc( const QString& pkgc ) Config::updateGlobalStorage() const
{ {
m_pkgc = pkgc; if ( m_model->packageCount() > 0 )
emit pkgcChanged( m_pkgc ); {
cWarning() << "Inconsistent package choices -- both model and single-selection QML";
}
if ( m_method == PackageChooserMethod::Legacy )
{
auto* gs = Calamares::JobQueue::instance()->globalStorage();
if ( m_packageChoice.has_value() )
{
gs->insert( make_gs_key( m_defaultId ), m_packageChoice.value() );
}
else
{
gs->remove( make_gs_key( m_defaultId ) );
}
}
else if ( m_method == PackageChooserMethod::Packages )
{
cWarning() << "Unsupported single-selection packagechooser method 'Packages'";
}
else
{
cWarning() << "Unknown packagechooser method" << smash( m_method );
}
}
void
Config::setPackageChoice( const QString& packageChoice )
{
if ( packageChoice.isEmpty() )
{
m_packageChoice.reset();
}
else
{
m_packageChoice = packageChoice;
}
emit packageChoiceChanged( m_packageChoice.value_or( QString() ) );
} }
QString QString
Config::prettyStatus() const Config::prettyStatus() const
{ {
return tr( "Install option: <strong>%1</strong>" ).arg( m_pkgc ); return tr( "Install option: <strong>%1</strong>" ).arg( m_packageChoice.value_or( tr( "None" ) ) );
} }
static void static void
@ -197,50 +243,38 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
PackageChooserMode::Required ); PackageChooserMode::Required );
m_method = PackageChooserMethodNames().find( CalamaresUtils::getString( configurationMap, "method" ), m_method = PackageChooserMethodNames().find( CalamaresUtils::getString( configurationMap, "method" ),
PackageChooserMethod::Legacy ); PackageChooserMethod::Legacy );
m_pkgc = CalamaresUtils::getString( configurationMap, "pkgc" );
if ( m_method == PackageChooserMethod::Legacy ) if ( m_method == PackageChooserMethod::Legacy )
{ {
const QString configId = CalamaresUtils::getString( configurationMap, "id" ); cDebug() << "Using module ID" << m_defaultId;
const QString base = QStringLiteral( "packagechooser_" );
if ( configId.isEmpty() )
{
if ( m_defaultId.id().isEmpty() )
{
// We got nothing to work with
m_id = base;
}
else
{
m_id = base + m_defaultId.id();
}
cDebug() << "Using default ID" << m_id << "from" << m_defaultId.toString();
}
else
{
m_id = base + configId;
cDebug() << "Using configured ID" << m_id;
}
} }
if ( configurationMap.contains( "items" ) ) if ( configurationMap.contains( "items" ) )
{ {
fillModel( m_model, configurationMap.value( "items" ).toList() ); fillModel( m_model, configurationMap.value( "items" ).toList() );
}
QString default_item_id = CalamaresUtils::getString( configurationMap, "default" ); QString default_item_id = CalamaresUtils::getString( configurationMap, "default" );
if ( !default_item_id.isEmpty() ) if ( !default_item_id.isEmpty() )
{
for ( int item_n = 0; item_n < m_model->packageCount(); ++item_n )
{ {
QModelIndex item_idx = m_model->index( item_n, 0 ); for ( int item_n = 0; item_n < m_model->packageCount(); ++item_n )
QVariant item_id = m_model->data( item_idx, PackageListModel::IdRole );
if ( item_id.toString() == default_item_id )
{ {
m_defaultModelIndex = item_idx; QModelIndex item_idx = m_model->index( item_n, 0 );
break; QVariant item_id = m_model->data( item_idx, PackageListModel::IdRole );
if ( item_id.toString() == default_item_id )
{
m_defaultModelIndex = item_idx;
break;
}
} }
} }
} }
else
{
setPackageChoice( CalamaresUtils::getString( configurationMap, "packageChoice" ) );
if ( m_method != PackageChooserMethod::Legacy )
{
cWarning() << "Single-selection QML module must use 'Legacy' method.";
}
}
} }

View File

@ -17,6 +17,7 @@
#include "modulesystem/InstanceKey.h" #include "modulesystem/InstanceKey.h"
#include <memory> #include <memory>
#include <optional>
enum class PackageChooserMode enum class PackageChooserMode
{ {
@ -40,7 +41,16 @@ class Config : public Calamares::ModuleSystem::Config
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY( QString pkgc READ pkgc WRITE setPkgc NOTIFY pkgcChanged ) /** @brief This is the single-select package-choice
*
* For (QML) modules that support only a single selection and
* just want to do things in a straightforward pick-this-one
* way, the packageChoice property is a (the) way to go.
*
* Writing to this property means that any other form of package-
* choice or selection is ignored.
*/
Q_PROPERTY( QString packageChoice READ packageChoice WRITE setPackageChoice NOTIFY packageChoiceChanged )
Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL ) Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL )
public: public:
@ -75,16 +85,21 @@ public:
* (and only) the packages in @p selected as selected. * (and only) the packages in @p selected as selected.
*/ */
void updateGlobalStorage( const QStringList& selected ) const; void updateGlobalStorage( const QStringList& selected ) const;
/// As updateGlobalStorage() with an empty selection list /** @brief Write selection to global storage
void fillGSSecondaryConfiguration() const { updateGlobalStorage( QStringList() ); } *
* Updates the GS keys for this packagechooser, marking **only**
* the package choice as selected. This assumes that the single-
* selection QML code is in use.
*/
void updateGlobalStorage() const;
QString pkgc() const { return m_pkgc; } QString packageChoice() const { return m_packageChoice.value_or( QString() ); }
void setPkgc( const QString& pkgc ); void setPackageChoice( const QString& packageChoice );
QString prettyStatus() const; QString prettyStatus() const;
signals: signals:
void pkgcChanged( QString pkgc ); void packageChoiceChanged( QString packageChoice );
void prettyStatusChanged(); void prettyStatusChanged();
private: private:
@ -95,12 +110,14 @@ private:
PackageChooserMode m_mode = PackageChooserMode::Optional; PackageChooserMode m_mode = PackageChooserMode::Optional;
/// How this module stores to GS /// How this module stores to GS
PackageChooserMethod m_method = PackageChooserMethod::Legacy; PackageChooserMethod m_method = PackageChooserMethod::Legacy;
/// Id (used to identify settings from this module in GS)
QString m_id;
/// Value to use for id if none is set in the config file /// Value to use for id if none is set in the config file
Calamares::ModuleSystem::InstanceKey m_defaultId; Calamares::ModuleSystem::InstanceKey m_defaultId;
/// QML selection /** @brief QML selection (for single-selection approaches)
QString m_pkgc; *
* If there is no value, then there has been no selection.
* Reading the property will return an empty QString.
*/
std::optional< QString > m_packageChoice;
}; };

View File

@ -15,11 +15,10 @@ mode: required
# #
# - "legacy" or "custom" or "contextualprocess" # - "legacy" or "custom" or "contextualprocess"
# When set to "legacy", writes a GlobalStorage value for the choice that # When set to "legacy", writes a GlobalStorage value for the choice that
# has been made. The key is *packagechooser_<id>*. Normally, the module's # has been made. The key is *packagechooser_<id>*. The module's
# instance name is used; see the *instances* section of `settings.conf`. # instance name is used; see the *instances* section of `settings.conf`.
# If there is just one packagechooser module, and no special instance is set, # If there is just one packagechooser module, and no special instance is set,
# resulting GS key is probably *packagechooser@packagechooser*. # resulting GS key is probably *packagechooser_packagechooser*.
# You can set *id* to change that, but it is not recommended.
# #
# The GS value is a comma-separated list of the IDs of the selected # The GS value is a comma-separated list of the IDs of the selected
# packages, or an empty string if none is selected. # packages, or an empty string if none is selected.
@ -33,15 +32,12 @@ mode: required
# consumption by the *packages* module (which should appear later # consumption by the *packages* module (which should appear later
# in the `exec` section. These package settings will then be handed # in the `exec` section. These package settings will then be handed
# off to whatever package manager is configured there. # off to whatever package manager is configured there.
# The *id* key is not used.
# #
# There is no need to put this module in the `exec` section. There # There is no need to put this module in the `exec` section. There
# are no jobs that this module provides. You should put **other** # are no jobs that this module provides. You should put **other**
# modules, either *contextualprocess* or *packages* or some custom # modules, either *contextualprocess* or *packages* or some custom
# module, in the `exec` section to do the actual work. # module, in the `exec` section to do the actual work.
method: legacy method: legacy
# The *id* key is used only in "legacy" mode
# id: ""
# Human-visible strings in this module. These are all optional. # Human-visible strings in this module. These are all optional.
@ -51,13 +47,13 @@ method: legacy
# Each key can have a [locale] added to it, which is used as # Each key can have a [locale] added to it, which is used as
# the translated string for that locale. For the strings # the translated string for that locale. For the strings
# associated with the "no-selection" item, see *items*, below # associated with the "no-selection" item, see *items*, below
# with the explicit id "". # with the explicit item-*id* "".
# #
labels: labels:
step: "Packages" step: "Packages"
step[nl]: "Pakketten" step[nl]: "Pakketten"
# (Optional) 'id' of pre-selected list-view item. # (Optional) item-*id* of pre-selected list-view item.
# Pre-selects one of the items below. # Pre-selects one of the items below.
# default: kde # default: kde

View File

@ -74,7 +74,7 @@ PackageChooserQmlViewStep::jobs() const
void void
PackageChooserQmlViewStep::onLeave() PackageChooserQmlViewStep::onLeave()
{ {
m_config->fillGSSecondaryConfiguration(); m_config->updateGlobalStorage();
} }
void void

View File

@ -1,25 +1,26 @@
# SPDX-FileCopyrightText: no # SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
# #
# Configuration for the low-density software chooser # Configuration for the low-density software chooser, QML implementation
--- #
# Software selection mode, to set whether the software packages # The example QML implementation uses single-selection, rather than
# can be chosen singly, or multiply. # a model for the available packages. That makes it simpler: the
# QML itself codes the available options, descriptions and images
# -- after all, this is **low density** selection, so a custom UI
# can make sense for the few choices that need to be made.
#
# #
# Possible modes are "optional", "required" (for zero-or-one or exactly-one)
# or "optionalmultiple", "requiredmultiple" (for zero-or-more
# or one-or-more).
mode: required
---
# Software installation method: # Software installation method:
# #
# - "legacy" or "custom" or "contextualprocess" # - "legacy" or "custom" or "contextualprocess"
# When set to "legacy", writes a GlobalStorage value for the choice that # When set to "legacy", writes a GlobalStorage value for the choice that
# has been made. The key is *packagechooser_<id>*. Normally, the module's # has been made. The key is *packagechooser_<id>*. The module's
# instance name is used; see the *instances* section of `settings.conf`. # instance name is used; see the *instances* section of `settings.conf`.
# If there is just one packagechooser module, and no special instance is set, # If there is just one packagechooserq module, and no special instance is set,
# resulting GS key is probably *packagechooser@packagechooser*. # resulting GS key is probably *packagechooser_packagechooserq*.
# You can set *id* to change that, but it is not recommended. # (Do note that the prefix of the GS key remains "packagechooser_")
# #
# The GS value is a comma-separated list of the IDs of the selected # The GS value is a comma-separated list of the IDs of the selected
# packages, or an empty string if none is selected. # packages, or an empty string if none is selected.
@ -33,16 +34,20 @@ mode: required
# consumption by the *packages* module (which should appear later # consumption by the *packages* module (which should appear later
# in the `exec` section. These package settings will then be handed # in the `exec` section. These package settings will then be handed
# off to whatever package manager is configured there. # off to whatever package manager is configured there.
# The *id* key is not used.
# #
# There is no need to put this module in the `exec` section. There # There is no need to put this module in the `exec` section. There
# are no jobs that this module provides. You should put **other** # are no jobs that this module provides. You should put **other**
# modules, either *contextualprocess* or *packages* or some custom # modules, either *contextualprocess* or *packages* or some custom
# module, in the `exec` section to do the actual work. # module, in the `exec` section to do the actual work.
#
method: legacy method: legacy
# The *id* key is used only in "legacy" mode
# id: ""
# The *pkgc* is used for setting the default selection in the QML view # The *packageChoice* value is used for setting the default selection
pkgc: libreoffice # in the QML view; this should match one of the keys used in the QML
# module for package names.
#
# (e.g. the sample QML uses "no_office_suite", "minimal_install" and
# "libreoffice" as possible choices).
#
packageChoice: libreoffice

View File

@ -80,12 +80,8 @@ Item {
} }
onCheckedChanged: { onCheckedChanged: {
if ( ! checked ) { if ( checked ) {
print("L not used") config.packageChoice = "libreoffice"
}
else {
config.pkgc = "libreoffice"
print( config.pkgc )
} }
} }
} }
@ -146,13 +142,8 @@ Item {
} }
onCheckedChanged: { onCheckedChanged: {
if ( ! checked ) { if ( checked ) {
print("not used") config.packageChoice = "no_office_suite"
//console.log("removed")
}
else {
print("No Office Suite")
config.pkgc = "no_office_suite"
} }
} }
} }
@ -215,12 +206,8 @@ Item {
} }
onCheckedChanged: { onCheckedChanged: {
if ( ! checked ) { if ( checked ) {
print("M not used") config.packageChoice = "minimal_install"
}
else {
print("minimal")
config.pkgc = "minimal_install"
} }
} }
} }

View File

@ -1,3 +1,8 @@
# === This file is part of Calamares - <https://calamares.io> ===
#
# SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
# SPDX-License-Identifier: BSD-2-Clause
#
if( NOT WITH_QML ) if( NOT WITH_QML )
calamares_skip_module( "summaryq (QML is not supported in this build)" ) calamares_skip_module( "summaryq (QML is not supported in this build)" )
return() return()

View File

@ -1,3 +1,5 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
--- ---
requirements: requirements:
internetCheckUrl: http://example.com internetCheckUrl: http://example.com

View File

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Nothing at all # Nothing at all
--- ---
bogus: 1 bogus: 1

View File

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Set to blank # Set to blank
--- ---
requirements: requirements:

View File

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Set to something broken # Set to something broken
--- ---
requirements: requirements:

View File

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Empty list # Empty list
--- ---
requirements: requirements:

View File

@ -1,6 +1,10 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Multiple, all valid
--- ---
requirements: requirements:
internetCheckUrl: internetCheckUrl:
- http://example.com - http://example.com
- http://bogus.example.com - http://bogus.example.com
- http://nonexistent.example.com - http://nonexistent.example.com

View File

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Multiple, all valid, in short-list form
--- ---
requirements: requirements:
internetCheckUrl: [ http://example.com, http://bogus.example.com, http://nonexistent.example.com ] internetCheckUrl: [ http://example.com, http://bogus.example.com, http://nonexistent.example.com ]

View File

@ -1,7 +1,10 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# "0" is a valid URL (?) but "" is not # "0" is a valid URL (?) but "" is not
--- ---
requirements: requirements:
internetCheckUrl: internetCheckUrl:
- http://example.com - http://example.com
- 0 - 0
- "" - ""