From 8b72c93d676fc2ed9c329a15250fe04243216bd8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 3 Jan 2019 15:38:20 +0100 Subject: [PATCH 01/19] [branding] Group the welcome-settings together --- src/branding/default/branding.desc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc index fcc307242..ade0a3609 100644 --- a/src/branding/default/branding.desc +++ b/src/branding/default/branding.desc @@ -8,6 +8,12 @@ componentName: default # same distribution. welcomeStyleCalamares: false +# Should the welcome image (productWelcome, below) be scaled +# up beyond its natural size? If false, the image does not grow +# with the window but remains the same size throughout (this +# may have surprising effects on HiDPI monitors). +welcomeExpandingLogo: true + # These are strings shown to the user in the user interface. # There is no provision for translating them -- since they # are names, the string is included as-is. @@ -32,12 +38,6 @@ strings: knownIssuesUrl: https://calamares.io/about/ releaseNotesUrl: https://calamares.io/about/ -# Should the welcome image (productWelcome, below) be scaled -# up beyond its natural size? If false, the image does not grow -# with the window but remains the same size throughout (this -# may have surprising effects on HiDPI monitors). -welcomeExpandingLogo: true - # These images are loaded from the branding module directory. # # productIcon is used as the window icon, and will (usually) be used From 2bb7a5f6869d4af44efb3ac1f188249f92ee0f07 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 3 Jan 2019 15:46:44 +0100 Subject: [PATCH 02/19] [branding] Document intended settings for window size - Control Calamares window size through the branding file - This is for #1062 and #1038 --- src/branding/default/branding.desc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc index ade0a3609..b51eaec2e 100644 --- a/src/branding/default/branding.desc +++ b/src/branding/default/branding.desc @@ -14,6 +14,21 @@ welcomeStyleCalamares: false # may have surprising effects on HiDPI monitors). welcomeExpandingLogo: true +# Size and expansion policy for Calamares. +# - "normal" or unset, expand as needed, use *windowSize* +# - "fullscreen", start as large as possible, ignore *windowSize* +# - "noexpand", never expand, use *windowSize* +windowExpanding: normal + +# Size of Calamares window, expressed as w,h. Both w and h +# may be either pixels (suffix px) or font-units (suffix em). +# e.g. "800px,600px" +# "60em,480px" +# This setting is ignored if "fullscreen" is selected for +# *windowExpanding*, above. If not set, use constants defined +# in CalamaresUtilsGui, 800x520. +windowSize: 800px,520px + # These are strings shown to the user in the user interface. # There is no provision for translating them -- since they # are names, the string is included as-is. From a8e19f5ee7f748e4ceeea0129cd33510af039fbb Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 11 Jan 2019 12:25:37 +0100 Subject: [PATCH 03/19] Changes: document the existence of resize options --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 88d8c7350..f7bd65007 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,9 @@ This release contains contributions from (alphabetically by first name): Calamares configurations (in particular, distro's can **add** configuration files and give them priority, instead of **forking** configuration files). + * The *branding* file now contains settings that control the size + and resize behavior of Calamares. See the branding file for + more documentation. ## Modules ## From fb4411356128a92e0c79b61fa6a617f81ca2dd9d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 11 Jan 2019 14:15:18 +0100 Subject: [PATCH 04/19] [libcalamares] Named enumeration support --- src/libcalamares/utils/NamedEnum.h | 88 ++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/libcalamares/utils/NamedEnum.h diff --git a/src/libcalamares/utils/NamedEnum.h b/src/libcalamares/utils/NamedEnum.h new file mode 100644 index 000000000..b28797288 --- /dev/null +++ b/src/libcalamares/utils/NamedEnum.h @@ -0,0 +1,88 @@ +/* === 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 . + */ + +/** @brief Support for "named" enumerations + * + * For tables which map string names to enum values, provide a NamedEnumTable + * which hangs on to an initializer_list of pairs of names and values. + * This table can be used with find() to map names to values, or + * values to names. A convenience function smash() is provided to help + * in printing integer (underlying) values of an enum. + */ + +#ifndef LIBCALAMARES_NAMEDENUM_H +#define LIBCALAMARES_NAMEDENUM_H + +#include + +#include +#include + +/** @brief Type for collecting parts of a named enum. */ +template +struct NamedEnumTable +{ + using string_t = QString; + using enum_t = T; + using pair_t = std::pair< string_t, enum_t >; + using type = std::initializer_list< pair_t >; +} ; + +/** @brief Find a name @p s in the @p table. */ +template +typename NamedEnumTable::enum_t find( const typename NamedEnumTable::type& table, const QString& s, bool& ok ) +{ + ok = false; + + for ( const auto p : table ) + if ( s == p.first ) + { + ok = true; + return p.second; + } + + // ok is still false + return table.begin()->second; +} + +/** @brief Find a value @p s in the @p table. */ +template +typename NamedEnumTable::enum_t find( const typename NamedEnumTable::type& table, const T s, bool& ok ) +{ + ok = false; + + for ( const auto p : table ) + if ( s == p.second) + { + ok = true; + return p.first; + } + + // ok is still false + return QString(); +} + +/** @brief Smashes an enum value to its underlying type. */ +template +constexpr typename std::underlying_type::type smash( const E e ) +{ + return static_cast::type>( e ); +} + + +#endif From 9c2a6b03e409d34e752f8cbcbee0acc7dbf67305 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 11 Jan 2019 14:30:21 +0100 Subject: [PATCH 05/19] [libcalamares] Slight refactor, move into NamedEnumTable - expand documentation on find() - make find() methods --- src/libcalamares/utils/NamedEnum.h | 80 +++++++++++++++++++----------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/src/libcalamares/utils/NamedEnum.h b/src/libcalamares/utils/NamedEnum.h index b28797288..c7b3ed9cf 100644 --- a/src/libcalamares/utils/NamedEnum.h +++ b/src/libcalamares/utils/NamedEnum.h @@ -41,41 +41,63 @@ struct NamedEnumTable using enum_t = T; using pair_t = std::pair< string_t, enum_t >; using type = std::initializer_list< pair_t >; -} ; -/** @brief Find a name @p s in the @p table. */ -template -typename NamedEnumTable::enum_t find( const typename NamedEnumTable::type& table, const QString& s, bool& ok ) -{ - ok = false; + type table; - for ( const auto p : table ) - if ( s == p.first ) - { - ok = true; - return p.second; - } + /** @brief Create a table of named enum values. + * + * Use braced-initialisation for NamedEnum, and remember that the + * elements of the list are **pairs**, e.g. + * + * static const NamedEnumTable c{ {"red", Colors::Red } }; + */ + NamedEnumTable( type v ) : table( v ) { /* static_assert( v.size() > 0 ); */ }; - // ok is still false - return table.begin()->second; -} + /** @brief Find a name @p s in the table. + * + * Searches case-insensitively. + * + * If the name @p s is not found, @p ok is set to false and + * the first enum value in the table is returned. Otherwise, + * @p ok is set to true and the corresponding value is returned. + * + */ + enum_t find( const string_t& s, bool& ok ) const + { + ok = false; -/** @brief Find a value @p s in the @p table. */ -template -typename NamedEnumTable::enum_t find( const typename NamedEnumTable::type& table, const T s, bool& ok ) -{ - ok = false; + for ( const auto p : table ) + if ( 0 == QString::compare( s, p.first, Qt::CaseInsensitive ) ) + { + ok = true; + return p.second; + } - for ( const auto p : table ) - if ( s == p.second) - { - ok = true; - return p.first; - } + // ok is still false + return table.begin()->second; + } - // ok is still false - return QString(); -} + /** @brief Find a value @p s in the table. + * + * If the value @p s is not found, @p ok is set to false and + * an empty string is returned. Otherwise, @p is set to true + * and the corresponding name is returned. + */ + string_t find( enum_t s, bool& ok ) const + { + ok = false; + + for ( const auto p : table ) + if ( s == p.second) + { + ok = true; + return p.first; + } + + // ok is still false + return string_t(); + } +} ; /** @brief Smashes an enum value to its underlying type. */ template From 194f693412bd35613162706e4887ea2017c418e6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 11 Jan 2019 14:32:45 +0100 Subject: [PATCH 06/19] [partition] Use new NamedEnum approach --- .../partition/gui/PartitionViewStep.cpp | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/modules/partition/gui/PartitionViewStep.cpp b/src/modules/partition/gui/PartitionViewStep.cpp index 0152f8bec..7d1791342 100644 --- a/src/modules/partition/gui/PartitionViewStep.cpp +++ b/src/modules/partition/gui/PartitionViewStep.cpp @@ -35,6 +35,7 @@ #include "CalamaresVersion.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" +#include "utils/NamedEnum.h" #include "utils/Retranslator.h" #include "widgets/WaitingWidget.h" #include "GlobalStorage.h" @@ -474,25 +475,17 @@ PartitionViewStep::onLeave() static PartitionActions::Choices::SwapChoice nameToChoice( QString name, bool& ok ) { - ok = false; - name = name.toLower(); - using namespace PartitionActions::Choices; - // Each return here first sets ok to true, returns enum value - if ( name == QStringLiteral( "none" ) ) - return( ok=true, SwapChoice::NoSwap ); - else if ( name == QStringLiteral( "small" ) ) - return( ok=true, SwapChoice::SmallSwap); - else if ( name == QStringLiteral( "suspend" ) ) - return( ok=true, SwapChoice::FullSwap ); - else if ( name == QStringLiteral( "reuse" ) ) - return( ok=true, SwapChoice::ReuseSwap ); - else if ( name == QStringLiteral( "file" ) ) - return( ok=true, SwapChoice::SwapFile ); - - ok = false; - return SwapChoice::NoSwap; + static const NamedEnumTable names { + { QStringLiteral( "none" ), SwapChoice::NoSwap }, + { QStringLiteral( "small" ), SwapChoice::SmallSwap }, + { QStringLiteral( "suspend" ), SwapChoice::FullSwap }, + { QStringLiteral( "reuse" ), SwapChoice::ReuseSwap }, + { QStringLiteral( "file" ), SwapChoice::SwapFile } + }; + + return names.find( name, ok ); } From 819a57e45883da1341cf2565d5596cf046fd57cd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 11 Jan 2019 17:35:06 +0100 Subject: [PATCH 07/19] [libcalamaresui] Store resize configuration - Use the named enums code for simplicity. --- src/libcalamaresui/Branding.cpp | 27 +++++++++++++++++++++++---- src/libcalamaresui/Branding.h | 13 ++++++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 086e20b7d..7f8e8c343 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -21,9 +21,10 @@ #include "GlobalStorage.h" #include "utils/CalamaresUtils.h" +#include "utils/ImageRegistry.h" #include "utils/Logger.h" +#include "utils/NamedEnum.h" #include "utils/YamlUtils.h" -#include "utils/ImageRegistry.h" #include #include @@ -107,12 +108,11 @@ Branding::Branding( const QString& brandingFilePath, bail( "The branding component name should match the name of the " "component directory." ); + initSimpleSettings( doc ); + if ( !doc[ "strings" ].IsMap() ) bail( "Syntax error in strings map." ); - m_welcomeStyleCalamares = doc[ "welcomeStyleCalamares" ].as< bool >( false ); - m_welcomeExpandingLogo = doc[ "welcomeExpandingLogo" ].as< bool >( true ); - QVariantMap strings = CalamaresUtils::yamlMapToVariant( doc[ "strings" ] ).toMap(); m_strings.clear(); @@ -288,6 +288,25 @@ Branding::setGlobals( GlobalStorage* globalStorage ) const } +void +Branding::initSimpleSettings( const YAML::Node& doc ) +{ + static const NamedEnumTable< WindowExpansion > weNames{ + { QStringLiteral( "normal" ), WindowExpansion::Normal }, + { QStringLiteral( "fullscreen" ), WindowExpansion::Fullscreen }, + { QStringLiteral( "noexpand" ), WindowExpansion::Fixed } + }; + + bool ok = false; + + m_welcomeStyleCalamares = doc[ "welcomeStyleCalamares" ].as< bool >( false ); + m_welcomeExpandingLogo = doc[ "welcomeExpandingLogo" ].as< bool >( true ); + m_windowExpansion = weNames.find( QString::fromStdString( doc[ "windowExpanding" ].as< std::string >() ), ok ); + if ( !ok ) + cWarning() << "Branding module-setting *windowExpanding* interpreted as" << weNames.find( m_windowExpansion, ok ); +} + + void Branding::bail( const QString& message ) { diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index fe9a83979..94136791c 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -27,6 +27,10 @@ #include #include +namespace YAML +{ + class Node; +} namespace Calamares { @@ -63,7 +67,7 @@ public: ProductIcon, ProductWelcome }; - + enum StyleEntry : short { SidebarBackground, @@ -72,6 +76,9 @@ public: SidebarTextHighlight }; + /** @brief Setting for how much the main window may expand. */ + enum class WindowExpansion { Normal, Fullscreen, Fixed } ; + static Branding* instance(); explicit Branding( const QString& brandingFilePath, @@ -115,8 +122,12 @@ private: QString m_slideshowPath; QString m_translationsPathPrefix; + /** @brief Initialize the simple settings below */ + void initSimpleSettings( const YAML::Node& doc ); + bool m_welcomeStyleCalamares; bool m_welcomeExpandingLogo; + WindowExpansion m_windowExpansion; }; template inline QString operator*(U e) { return Branding::instance()->string( e ); } From e28aeebb4890543979081c3f58617193669445e9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 11 Jan 2019 19:48:11 +0100 Subject: [PATCH 08/19] [libcalamares] Introduce helper NamedSuffix template For (all?) those cases where we have configuration with a value followed by a unit, introduce a class that uses the NamedEnum properties to make parsing and split-up easier. --- src/libcalamares/utils/NamedSuffix.h | 62 ++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/libcalamares/utils/NamedSuffix.h diff --git a/src/libcalamares/utils/NamedSuffix.h b/src/libcalamares/utils/NamedSuffix.h new file mode 100644 index 000000000..db87026ae --- /dev/null +++ b/src/libcalamares/utils/NamedSuffix.h @@ -0,0 +1,62 @@ +/* === 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 . + */ + +/** @brief Support for unit-suffixed values. + */ + +#ifndef LIBCALAMARES_NAMEDSUFFIX_H +#define LIBCALAMARES_NAMEDSUFFIX_H + +#include "NamedEnum.h" + +template +class NamedSuffix +{ +public: + using unit_t = T; + + NamedSuffix() + : m_value(0) + , m_unit( none ) + { + } + + int value() const { return m_value; } + T unit() const { return m_unit; } + + bool isValid() const { return m_unit != none; } + +protected: + NamedSuffix( const NamedEnumTable& table, const QString& s ) + : NamedSuffix() + { + for( const auto suffix : table.table ) + if ( s.endsWith( suffix.first ) ) + { + m_value = s.left( s.length() - suffix.first.length() + 1 ).toInt(); + m_unit = suffix.second; + break; + } + } + + int m_value; + T m_unit; +}; + + +#endif From ef33aa01f3618da4bbe77a9961fbe1099bbe36be Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 11 Jan 2019 19:49:39 +0100 Subject: [PATCH 09/19] [fsresizer] Port to NamedSuffix template --- src/modules/fsresizer/ResizeFSJob.cpp | 46 ++++++++++----------------- src/modules/fsresizer/ResizeFSJob.h | 30 +++++++---------- src/modules/fsresizer/Tests.cpp | 26 +++++++-------- 3 files changed, 41 insertions(+), 61 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 4df41a7d4..8fccf6e8b 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -39,46 +39,32 @@ #include "modules/partition/core/PartitionIterator.h" -ResizeFSJob::RelativeSize::RelativeSize() - : m_value( 0 ) - , m_unit( None ) + +static const NamedEnumTable& +unitSuffixes() { -} + using Unit = ResizeFSJob::RelativeUnit; + static const NamedEnumTable names{ + { "%", Unit::Percent }, + { "MiB", Unit::Absolute } + }; -template -void matchUnitSuffix( - const QString& s, - const char ( &suffix )[N], - ResizeFSJob::RelativeSize::Unit matchedUnit, - int& value, - ResizeFSJob::RelativeSize::Unit& unit -) -{ - if ( s.endsWith( suffix ) ) - { - value = s.left( s.length() - N + 1 ).toInt(); - unit = matchedUnit; - } + return names; } - ResizeFSJob::RelativeSize::RelativeSize( const QString& s ) - : m_value( 0 ) - , m_unit( None ) + : NamedSuffix( unitSuffixes(), s ) { - matchUnitSuffix( s, "%", Percent, m_value, m_unit ); - matchUnitSuffix( s, "MiB", Absolute, m_value, m_unit ); - - if ( ( unit() == Percent ) && ( value() > 100 ) ) + if ( ( unit() == RelativeUnit::Percent ) && ( value() > 100 ) ) { cDebug() << "Percent value" << value() << "is not valid."; m_value = 0; - m_unit = None; + m_unit = RelativeUnit::None; } if ( !m_value ) - m_unit = None; + m_unit = RelativeUnit::None; } qint64 @@ -91,11 +77,11 @@ ResizeFSJob::RelativeSize::apply( qint64 totalSectors, qint64 sectorSize ) switch ( m_unit ) { - case None: + case unit_t::None: return -1; - case Absolute: + case unit_t::Absolute: return CalamaresUtils::MiBtoBytes( value() ) / sectorSize; - case Percent: + case unit_t::Percent: if ( value() == 100 ) return totalSectors; // Common-case, avoid futzing around else diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index c34ccb865..d575f18a9 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -24,7 +24,8 @@ #include -#include +#include "utils/NamedSuffix.h" +#include "utils/PluginFactory.h" #include @@ -37,31 +38,28 @@ class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob Q_OBJECT public: + enum class RelativeUnit + { + None, + Percent, + Absolute + }; + /** @brief Size expressions * * Sizes can be specified in MiB or percent (of the device they * are on). This class handles parsing of such strings from the * config file. */ - class RelativeSize + class RelativeSize : public NamedSuffix { public: - RelativeSize(); + RelativeSize() : NamedSuffix() { }; RelativeSize( const QString& ); - enum Unit - { - None, - Percent, - Absolute - }; - - int value() const { return m_value; } - Unit unit() const { return m_unit; } - bool isValid() const { - return ( unit() != None ) && ( value() > 0 ); + return ( unit() != RelativeUnit::None ) && ( value() > 0 ); } /** @brief Apply this size to the number of sectors @p totalSectors . @@ -80,10 +78,6 @@ public: * Equivalent to apply( d->totalLogical(), d->logicalSize() ) */ qint64 apply( Device* d ); - - private: - int m_value; - Unit m_unit; } ; explicit ResizeFSJob( QObject* parent = nullptr ); diff --git a/src/modules/fsresizer/Tests.cpp b/src/modules/fsresizer/Tests.cpp index 255153fa2..8f6bb48c5 100644 --- a/src/modules/fsresizer/Tests.cpp +++ b/src/modules/fsresizer/Tests.cpp @@ -54,13 +54,13 @@ FSResizerTests::initTestCase() void FSResizerTests::testConfigurationRobust() { ResizeFSJob j; - + // Empty config j.setConfigurationMap( QVariantMap() ); QVERIFY( j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::None ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::None ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::None ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::None ); // Config is missing fs and dev, so it isn't valid YAML::Node doc0 = YAML::Load( R"(--- @@ -70,17 +70,17 @@ atleast: 600MiB j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::None ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::None ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::None ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::None ); QCOMPARE( j.m_size.value(), 0 ); QCOMPARE( j.m_atleast.value(), 0 ); -} +} void FSResizerTests::testConfigurationValues() { ResizeFSJob j; - // Check both + // Check both YAML::Node doc0 = YAML::Load( R"(--- fs: / size: 100% @@ -89,8 +89,8 @@ atleast: 600MiB j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( !j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::Percent ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::Absolute ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::Percent ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::Absolute ); QCOMPARE( j.m_size.value(), 100 ); QCOMPARE( j.m_atleast.value(), 600 ); @@ -104,8 +104,8 @@ atleast: 127 % j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( !j.m_fsname.isEmpty() ); QVERIFY( !j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::Absolute ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::Percent ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::Absolute ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::Percent ); QCOMPARE( j.m_size.value(), 72 ); QCOMPARE( j.m_atleast.value(), 127 ); @@ -119,8 +119,8 @@ size: 71MiB j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( !j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::Absolute ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::None ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::Absolute ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::None ); QCOMPARE( j.m_size.value(), 71 ); QCOMPARE( j.m_atleast.value(), 0 ); } From 99a19c7c6b4f05706b4760ac9b97283a34c155d4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 11:50:06 +0100 Subject: [PATCH 10/19] [libcalamares] Document NamedSuffix - Add more constructors - Make the table-constructor public, no need to force subclassing on everyone - Declare some useful API - Document the bits. --- src/libcalamares/utils/NamedSuffix.h | 60 ++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/libcalamares/utils/NamedSuffix.h b/src/libcalamares/utils/NamedSuffix.h index db87026ae..4da829ad7 100644 --- a/src/libcalamares/utils/NamedSuffix.h +++ b/src/libcalamares/utils/NamedSuffix.h @@ -17,6 +17,23 @@ */ /** @brief Support for unit-suffixed values. + * + * This combines a value with an (enum) unit indicating what kind + * of value it is, e.g. 10 meters, or 64 pixels. Includes simple + * parsing support for the values written as strings like , + * e.g. "10m" or "64px". + * + * When a suffixed unit value needs validation, define an isValid() + * method; similarly for simple construction from a string (with a fixed + * table of suffixes). Typical use then looks like: + * + * class MyUnit : public NamedSuffix + * { + * public: + * using NamedSuffix::NamedSuffix; // Keep existing constructors + * MyUnit( const QString& s ); + * bool isValid() const; + * } ; */ #ifndef LIBCALAMARES_NAMEDSUFFIX_H @@ -24,24 +41,34 @@ #include "NamedEnum.h" -template +/** @brief Template that takes the enum type to work with and a special none-enum. */ +template class NamedSuffix { public: using unit_t = T; + static constexpr unit_t none = _none; + + /** @brief Empty value. */ NamedSuffix() : m_value(0) , m_unit( none ) { } - int value() const { return m_value; } - T unit() const { return m_unit; } - - bool isValid() const { return m_unit != none; } + /** @brief Specific value and unit. */ + NamedSuffix( int value, unit_t unit ) + : m_value( value ) + , m_unit( unit ) + { + } -protected: + /** @brief Construct value and unit from string. + * + * This parses the given string @p s by comparing with the suffixes + * in @p table and uses the first matching suffix as the unit. + */ NamedSuffix( const NamedEnumTable& table, const QString& s ) : NamedSuffix() { @@ -54,8 +81,27 @@ protected: } } + + /** @brief Construct value from string. + * + * This is not defined in the template, because it should probably + * delegate to the constructor above with a fixed table. + */ + NamedSuffix( const QString& s ); + + int value() const { return m_value; } + unit_t unit() const { return m_unit; } + + /** @brief Check that a value-unit combination is valid. + * + * This is not defined in the template, because validity (e.g. + * range of acceptable values) depends on the kind of unit. + */ + bool isValid() const; + +protected: int m_value; - T m_unit; + unit_t m_unit; }; From 32ab377e43cade28c12898983b812f32fd1e30f8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 12:06:04 +0100 Subject: [PATCH 11/19] [libcalamaresui] Record branding window-size --- src/libcalamaresui/Branding.cpp | 42 ++++++++++++++++++++++++++++++--- src/libcalamaresui/Branding.h | 21 +++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 7f8e8c343..ecba9c27d 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -21,6 +21,7 @@ #include "GlobalStorage.h" #include "utils/CalamaresUtils.h" +#include "utils/CalamaresUtilsGui.h" #include "utils/ImageRegistry.h" #include "utils/Logger.h" #include "utils/NamedEnum.h" @@ -77,6 +78,17 @@ const QStringList Branding::s_styleEntryStrings = "sidebarTextHighlight" }; +static const NamedEnumTable& +windowDimensions() +{ + using Unit = Branding::WindowDimensionUnit; + static const NamedEnumTable names{ + {"px", Unit::Pixies}, + {"em", Unit::Fonties} + }; + + return names; +} Branding::Branding( const QString& brandingFilePath, QObject* parent ) @@ -287,23 +299,47 @@ Branding::setGlobals( GlobalStorage* globalStorage ) const globalStorage->insert( "branding", brandingMap ); } +bool +Branding::WindowDimension::isValid() const +{ + return ( unit() != none ) && ( value() > 0 ); +} void Branding::initSimpleSettings( const YAML::Node& doc ) { - static const NamedEnumTable< WindowExpansion > weNames{ + static const NamedEnumTable< WindowExpansion > expansionNames{ { QStringLiteral( "normal" ), WindowExpansion::Normal }, { QStringLiteral( "fullscreen" ), WindowExpansion::Fullscreen }, { QStringLiteral( "noexpand" ), WindowExpansion::Fixed } }; + static const NamedEnumTable< WindowDimensionUnit > dimensionNames{ + { QStringLiteral( "px" ), WindowDimensionUnit::Pixies }, + { QStringLiteral( "em" ), WindowDimensionUnit::Fonties } + }; bool ok = false; m_welcomeStyleCalamares = doc[ "welcomeStyleCalamares" ].as< bool >( false ); m_welcomeExpandingLogo = doc[ "welcomeExpandingLogo" ].as< bool >( true ); - m_windowExpansion = weNames.find( QString::fromStdString( doc[ "windowExpanding" ].as< std::string >() ), ok ); + m_windowExpansion = expansionNames.find( QString::fromStdString( doc[ "windowExpanding" ].as< std::string >() ), ok ); if ( !ok ) - cWarning() << "Branding module-setting *windowExpanding* interpreted as" << weNames.find( m_windowExpansion, ok ); + cWarning() << "Branding module-setting *windowExpanding* interpreted as" << expansionNames.find( m_windowExpansion, ok ); + + QString windowSize = QString::fromStdString( doc[ "windowSize" ].as< std::string >() ); + if ( !windowSize.isEmpty() ) + { + auto l = windowSize.split( ',' ); + if ( l.count() == 2 ) + { + m_windowWidth = WindowDimension( dimensionNames, l[0] ); + m_windowHeight = WindowDimension( dimensionNames, l[1] ); + } + } + if ( !m_windowWidth.isValid() || m_windowWidth.value() < CalamaresUtils::windowMinimumWidth ) + m_windowWidth = WindowDimension( CalamaresUtils::windowPreferredWidth, WindowDimensionUnit::Pixies ); + if ( !m_windowHeight.isValid() || m_windowHeight.value() < CalamaresUtils::windowMinimumHeight ) + m_windowHeight = WindowDimension( CalamaresUtils::windowPreferredHeight, WindowDimensionUnit::Pixies ); } diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 94136791c..611ce6c12 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -23,6 +23,8 @@ #include "UiDllMacro.h" #include "Typedefs.h" +#include "utils/NamedSuffix.h" + #include #include #include @@ -78,6 +80,18 @@ public: /** @brief Setting for how much the main window may expand. */ enum class WindowExpansion { Normal, Fullscreen, Fixed } ; + /** @brief Setting for the main window size. + * + * The units are pixels (Pixies) or something-based-on-fontsize (Fonties), which + * we suffix as "em", e.g. "600px" or "32em". + */ + enum class WindowDimensionUnit { None, Pixies, Fonties }; + class WindowDimension : public NamedSuffix + { + public: + using NamedSuffix::NamedSuffix; + bool isValid() const; + } ; static Branding* instance(); @@ -97,6 +111,10 @@ public: bool welcomeStyleCalamares() const { return m_welcomeStyleCalamares; } bool welcomeExpandingLogo() const { return m_welcomeExpandingLogo; } + QPair< WindowDimension, WindowDimension > windowSize() const + { + return QPair< WindowDimension, WindowDimension >( m_windowWidth, m_windowHeight ); + } /** * Creates a map called "branding" in the global storage, and inserts an @@ -128,6 +146,9 @@ private: bool m_welcomeStyleCalamares; bool m_welcomeExpandingLogo; WindowExpansion m_windowExpansion; + + WindowDimension m_windowHeight, m_windowWidth; + }; template inline QString operator*(U e) { return Branding::instance()->string( e ); } From f6c69db9ffeb431709d61aa87b8bbce845b48065 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 12:23:38 +0100 Subject: [PATCH 12/19] [calamares] Use branding-settings for initial window-size --- src/calamares/CalamaresWindow.cpp | 36 +++++++++++++++++++------------ 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp index 9f2ab6472..bbc51750a 100644 --- a/src/calamares/CalamaresWindow.cpp +++ b/src/calamares/CalamaresWindow.cpp @@ -35,6 +35,18 @@ #include #include +static inline int +windowDimensionToPixels( const Calamares::Branding::WindowDimension& u ) +{ + if ( !u.isValid() ) + return 0; + if ( u.unit() == Calamares::Branding::WindowDimensionUnit::Pixies ) + return u.value(); + if ( u.unit() == Calamares::Branding::WindowDimensionUnit::Fonties ) + return u.value() * CalamaresUtils::defaultFontHeight(); + return 0; +} + CalamaresWindow::CalamaresWindow( QWidget* parent ) : QWidget( parent ) , m_debugWindow( nullptr ) @@ -45,24 +57,24 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) .arg( *Calamares::Branding::ProductName ) ); ) + const Calamares::Branding* const branding = Calamares::Branding::instance(); + using CalamaresUtils::windowMinimumHeight; using CalamaresUtils::windowMinimumWidth; using CalamaresUtils::windowPreferredHeight; using CalamaresUtils::windowPreferredWidth; QSize availableSize = qApp->desktop()->availableGeometry( this ).size(); - - cDebug() << "Available size" << availableSize; - - if ( ( availableSize.width() < windowPreferredWidth ) || ( availableSize.height() < windowPreferredHeight ) ) - cDebug() << " Small screen detected."; QSize minimumSize( qBound( windowMinimumWidth, availableSize.width(), windowPreferredWidth ), qBound( windowMinimumHeight, availableSize.height(), windowPreferredHeight ) ); setMinimumSize( minimumSize ); + cDebug() << "Available desktop" << availableSize << "minimum size" << minimumSize; + + auto brandingSizes = branding->windowSize(); - int w = qBound( minimumSize.width(), CalamaresUtils::defaultFontHeight() * 60, availableSize.width() ); - int h = qBound( minimumSize.height(), CalamaresUtils::defaultFontHeight() * 36, availableSize.height() ); + int w = qBound( minimumSize.width(), windowDimensionToPixels( brandingSizes.first ), availableSize.width() ); + int h = qBound( minimumSize.height(), windowDimensionToPixels( brandingSizes.second ), availableSize.height() ); cDebug() << " Proposed window size:" << w << h; resize( w, h ); @@ -85,18 +97,14 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) { QPalette plt = sideBox->palette(); sideBox->setAutoFillBackground( true ); - plt.setColor( sideBox->backgroundRole(), Calamares::Branding::instance()-> - styleString( Calamares::Branding::SidebarBackground ) ); - plt.setColor( sideBox->foregroundRole(), Calamares::Branding::instance()-> - styleString( Calamares::Branding::SidebarText ) ); + plt.setColor( sideBox->backgroundRole(),branding->styleString( Calamares::Branding::SidebarBackground ) ); + plt.setColor( sideBox->foregroundRole(), branding->styleString( Calamares::Branding::SidebarText ) ); sideBox->setPalette( plt ); logoLabel->setPalette( plt ); } logoLabel->setAlignment( Qt::AlignCenter ); logoLabel->setFixedSize( 80, 80 ); - logoLabel->setPixmap( Calamares::Branding::instance()-> - image( Calamares::Branding::ProductLogo, - logoLabel->size() ) ); + logoLabel->setPixmap( branding->image( Calamares::Branding::ProductLogo, logoLabel->size() ) ); logoLayout->addWidget( logoLabel ); logoLayout->addStretch(); From 0648a3facfcf06839b9af9561793501da6427b56 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 12:49:58 +0100 Subject: [PATCH 13/19] [fsresizer] Be explicit about type of string --- src/modules/fsresizer/ResizeFSJob.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 8fccf6e8b..6394075ba 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -46,8 +46,8 @@ unitSuffixes() using Unit = ResizeFSJob::RelativeUnit; static const NamedEnumTable names{ - { "%", Unit::Percent }, - { "MiB", Unit::Absolute } + { QStringLiteral( "%" ), Unit::Percent }, + { QStringLiteral( "MiB" ), Unit::Absolute } }; return names; From 097927eb3ec482ede633263c7630975c55b47c66 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 13:23:14 +0100 Subject: [PATCH 14/19] [libcalamares] Fix off-by-one in taking substring for value --- src/libcalamares/utils/NamedSuffix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamares/utils/NamedSuffix.h b/src/libcalamares/utils/NamedSuffix.h index 4da829ad7..97568d1da 100644 --- a/src/libcalamares/utils/NamedSuffix.h +++ b/src/libcalamares/utils/NamedSuffix.h @@ -75,7 +75,7 @@ public: for( const auto suffix : table.table ) if ( s.endsWith( suffix.first ) ) { - m_value = s.left( s.length() - suffix.first.length() + 1 ).toInt(); + m_value = s.left( s.length() - suffix.first.length() ).toInt(); m_unit = suffix.second; break; } From 79cee26b33215ca90c8b1d3066d2d368af2de60f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 13:23:44 +0100 Subject: [PATCH 15/19] [libcalamares] Switch to std::vector Keeping std::initializer_list around is fraught. Causes segfaults because I'm not keeping the underlying temporary array around properly. Switch to vectors because those initialize from the underlying array. TODO: look into making this sufficiently constexpr -- perhaps just use std::array and make find() work on that. --- src/libcalamares/utils/NamedEnum.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/utils/NamedEnum.h b/src/libcalamares/utils/NamedEnum.h index c7b3ed9cf..69abf4bd1 100644 --- a/src/libcalamares/utils/NamedEnum.h +++ b/src/libcalamares/utils/NamedEnum.h @@ -40,7 +40,7 @@ struct NamedEnumTable using string_t = QString; using enum_t = T; using pair_t = std::pair< string_t, enum_t >; - using type = std::initializer_list< pair_t >; + using type = std::vector< pair_t >; type table; @@ -51,7 +51,7 @@ struct NamedEnumTable * * static const NamedEnumTable c{ {"red", Colors::Red } }; */ - NamedEnumTable( type v ) : table( v ) { /* static_assert( v.size() > 0 ); */ }; + NamedEnumTable( const std::initializer_list< pair_t >& v ) : table( v ) { /* static_assert( v.size() > 0 ); */ }; /** @brief Find a name @p s in the table. * From 80569a746f6cd2de45bced81e264aebf02215f42 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 13:42:41 +0100 Subject: [PATCH 16/19] [libcalamaresui] Relax validity check in branding - A size of 64em has a value less than 1024, which is the minimum size **in pixels**. The check doesn't make sense as-is and would have to take the unit into account. Leave that to clients of branding (e.g. CalamaresWindow, which already does this). --- src/libcalamaresui/Branding.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index ecba9c27d..08deb7263 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -336,9 +336,9 @@ Branding::initSimpleSettings( const YAML::Node& doc ) m_windowHeight = WindowDimension( dimensionNames, l[1] ); } } - if ( !m_windowWidth.isValid() || m_windowWidth.value() < CalamaresUtils::windowMinimumWidth ) + if ( !m_windowWidth.isValid() ) m_windowWidth = WindowDimension( CalamaresUtils::windowPreferredWidth, WindowDimensionUnit::Pixies ); - if ( !m_windowHeight.isValid() || m_windowHeight.value() < CalamaresUtils::windowMinimumHeight ) + if ( !m_windowHeight.isValid() ) m_windowHeight = WindowDimension( CalamaresUtils::windowPreferredHeight, WindowDimensionUnit::Pixies ); } From 866797a6c949c9595b033c84122947636df66026 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 14:17:39 +0100 Subject: [PATCH 17/19] [calamares] Support starting fullscreen --- src/calamares/CalamaresApplication.cpp | 8 +++++++- src/libcalamaresui/Branding.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index 0b715d6df..f668722fd 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -348,7 +348,13 @@ void CalamaresApplication::initViewSteps() { cDebug() << "STARTUP: loadModules for all modules done"; - m_mainwindow->show(); + if ( Calamares::Branding::instance()->windowMaximize() ) + { + m_mainwindow->setWindowFlag( Qt::FramelessWindowHint ); + m_mainwindow->showMaximized(); + } + else + m_mainwindow->show(); ProgressTreeModel* m = new ProgressTreeModel( nullptr ); ProgressTreeView::instance()->setModel( m ); cDebug() << "STARTUP: Window now visible and ProgressTreeView populated"; diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 611ce6c12..cd1be1386 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -111,6 +111,7 @@ public: bool welcomeStyleCalamares() const { return m_welcomeStyleCalamares; } bool welcomeExpandingLogo() const { return m_welcomeExpandingLogo; } + bool windowMaximize() const { return m_windowExpansion == WindowExpansion::Fullscreen; } QPair< WindowDimension, WindowDimension > windowSize() const { return QPair< WindowDimension, WindowDimension >( m_windowWidth, m_windowHeight ); From ef94b1f689904cab43e640b2b3643f1bb54aa693 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 14:25:01 +0100 Subject: [PATCH 18/19] [calamares] Support noexpand - When in noexpand mode, just don't grow the window, and assume widgets elsewhere will get scrollbars automatically. --- src/branding/default/branding.desc | 2 +- src/calamares/CalamaresWindow.cpp | 3 ++- src/libcalamaresui/Branding.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc index b51eaec2e..5fefc422a 100644 --- a/src/branding/default/branding.desc +++ b/src/branding/default/branding.desc @@ -17,7 +17,7 @@ welcomeExpandingLogo: true # Size and expansion policy for Calamares. # - "normal" or unset, expand as needed, use *windowSize* # - "fullscreen", start as large as possible, ignore *windowSize* -# - "noexpand", never expand, use *windowSize* +# - "noexpand", don't expand automatically, use *windowSize* windowExpanding: normal # Size of Calamares window, expressed as w,h. Both w and h diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp index bbc51750a..7e619a7be 100644 --- a/src/calamares/CalamaresWindow.cpp +++ b/src/calamares/CalamaresWindow.cpp @@ -147,7 +147,8 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) CalamaresUtils::unmarginLayout( mainLayout ); m_viewManager = Calamares::ViewManager::instance( this ); - connect( m_viewManager, &Calamares::ViewManager::enlarge, this, &CalamaresWindow::enlarge ); + if ( branding->windowExpands() ) + connect( m_viewManager, &Calamares::ViewManager::enlarge, this, &CalamaresWindow::enlarge ); mainLayout->addWidget( m_viewManager->centralWidget() ); } diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index cd1be1386..d97e0595a 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -112,6 +112,7 @@ public: bool welcomeStyleCalamares() const { return m_welcomeStyleCalamares; } bool welcomeExpandingLogo() const { return m_welcomeExpandingLogo; } bool windowMaximize() const { return m_windowExpansion == WindowExpansion::Fullscreen; } + bool windowExpands() const { return m_windowExpansion != WindowExpansion::Fixed; } QPair< WindowDimension, WindowDimension > windowSize() const { return QPair< WindowDimension, WindowDimension >( m_windowWidth, m_windowHeight ); From 12665192ae79e10b623bf9bff5e76f084fb6747f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 14 Jan 2019 15:30:44 +0100 Subject: [PATCH 19/19] [libcalamaresui] Defend against missing config settings --- src/libcalamaresui/Branding.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 08deb7263..15c1c6125 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -305,6 +305,16 @@ Branding::WindowDimension::isValid() const return ( unit() != none ) && ( value() > 0 ); } + +/// @brief Guard against cases where the @p key doesn't exist in @p doc +static inline QString +getString( const YAML::Node& doc, const char* key ) +{ + if ( doc[key] ) + return QString::fromStdString( doc[key].as< std::string >() ); + return QString(); +} + void Branding::initSimpleSettings( const YAML::Node& doc ) { @@ -322,11 +332,11 @@ Branding::initSimpleSettings( const YAML::Node& doc ) m_welcomeStyleCalamares = doc[ "welcomeStyleCalamares" ].as< bool >( false ); m_welcomeExpandingLogo = doc[ "welcomeExpandingLogo" ].as< bool >( true ); - m_windowExpansion = expansionNames.find( QString::fromStdString( doc[ "windowExpanding" ].as< std::string >() ), ok ); + m_windowExpansion = expansionNames.find( getString( doc, "windowExpanding" ), ok ); if ( !ok ) cWarning() << "Branding module-setting *windowExpanding* interpreted as" << expansionNames.find( m_windowExpansion, ok ); - QString windowSize = QString::fromStdString( doc[ "windowSize" ].as< std::string >() ); + QString windowSize = getString( doc, "windowSize" ); if ( !windowSize.isEmpty() ) { auto l = windowSize.split( ',' );