[libcalamares] Replace loadPresets() with an applicative style

Build up the list of known presets by what the Config-object
expects, not by what the Config file provides. This allows
early detection of mis-matched configurations.

Presets can only apply to Q_PROPERTY properties, and the
preset must match the property name.
main
Adriaan de Groot 4 years ago
parent 8b10a9cfc2
commit d8dff3dc65

@ -10,6 +10,7 @@
#include "Config.h"
#include "Preset.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
namespace Calamares
@ -33,47 +34,63 @@ Config::Config( QObject* parent )
Config::~Config() {}
void
Config::loadPresets( const QVariantMap& configurationMap )
bool
Config::isEditable( const QString& fieldName ) const
{
const QString key( "presets" );
if ( !configurationMap.contains( key ) )
if ( m_unlocked )
{
d->m_presets.reset();
return;
return true;
}
bool bogus = true;
d->m_presets = std::make_unique< Presets >( CalamaresUtils::getSubMap( configurationMap, key, bogus ) );
if ( d && d->m_presets )
{
return d->m_presets->isEditable( fieldName );
}
else
{
cWarning() << "Checking isEditable, but no presets are configured.";
}
return true;
}
void
Config::loadPresets( const QVariantMap& configurationMap, const QStringList& recognizedKeys )
Config::ApplyPresets::ApplyPresets( Calamares::ModuleSystem::Config& c, const QVariantMap& configurationMap )
: m_c( c )
, m_bogus( true )
, m_map( CalamaresUtils::getSubMap( configurationMap, "presets", m_bogus ) )
{
const QString key( "presets" );
if ( !configurationMap.contains( key ) )
c.m_unlocked = true;
if ( !c.d->m_presets )
{
d->m_presets.reset();
return;
c.d->m_presets = std::make_unique< Presets >();
}
bool bogus = true;
d->m_presets
= std::make_unique< Presets >( CalamaresUtils::getSubMap( configurationMap, key, bogus ), recognizedKeys );
}
bool
Config::isEditable( const QString& fieldName ) const
Config::ApplyPresets&
Config::ApplyPresets::apply( const char* fieldName )
{
if ( m_unlocked )
const auto prop = m_c.property( fieldName );
if ( !prop.isValid() )
{
return true;
cWarning() << "Applying invalid property" << fieldName;
}
if ( d && d->m_presets )
else
{
return d->m_presets->isEditable( fieldName );
const QString key( fieldName );
if ( !key.isEmpty() && m_map.contains( key ) )
{
QVariantMap m = CalamaresUtils::getSubMap( m_map, key, m_bogus );
QVariant value = m[ "value" ];
bool editable = CalamaresUtils::getBool( m, "editable", true );
if ( value.isValid() )
{
m_c.setProperty( fieldName, value );
}
m_c.d->m_presets->append( PresetField { key, value, editable } );
}
}
return true;
return *this;
}
} // namespace ModuleSystem
} // namespace Calamares

@ -58,8 +58,28 @@ public Q_SLOTS:
bool isEditable( const QString& fieldName ) const;
protected:
void loadPresets( const QVariantMap& configurationMap );
void loadPresets( const QVariantMap& configurationMap, const QStringList& recognizedKeys );
friend class ApplyPresets;
/** @brief "Builder" class for presets
*
* Derived classes should instantiate this (with themselves,
* and the whole configuration map that is passed to
* setConfigurationMap()) and then call .apply() to apply
* the presets specified in the configuration to the **named**
* QObject properties.
*/
class ApplyPresets
{
public:
ApplyPresets( Config& c, const QVariantMap& configurationMap );
~ApplyPresets() { m_c.m_unlocked = false; }
ApplyPresets& apply( const char* fieldName );
private:
Config& m_c;
bool m_bogus = true;
const QVariantMap m_map;
};
private:
class Private;

@ -62,6 +62,7 @@ Presets::isEditable( const QString& fieldName ) const
return p.editable;
}
}
cWarning() << "Checking isEditable for unknown field" << fieldName;
return true;
}

@ -36,8 +36,10 @@ namespace ModuleSystem
struct PresetField
{
QString fieldName;
QString value;
QVariant value;
bool editable = true;
bool isValid() const { return !fieldName.isEmpty(); }
};
/** @brief All the presets for one UI entity
@ -62,6 +64,14 @@ public:
*/
Presets( const QVariantMap& configurationMap, const QStringList& recognizedKeys );
/** @brief Creates an empty presets map
*
* This constructor is primarily intended for use by the ApplyPresets
* helper class, which will reserve suitable space and load
* presets on-demand.
*/
Presets() = default;
/** @brief Is the given @p fieldName editable?
*
* Fields are editable by default, so if there is no explicit setting,

@ -183,7 +183,7 @@ Config::setSudoersGroup( const QString& group )
void
Config::setLoginName( const QString& login )
{
if ( login != m_loginName )
if ( login != m_loginName && isEditable( QStringLiteral( "loginName" ) ) )
{
m_customLoginName = !login.isEmpty();
m_loginName = login;
@ -393,6 +393,11 @@ makeHostnameSuggestion( const QStringList& parts )
void
Config::setFullName( const QString& name )
{
if ( !isEditable( QStringLiteral( "fullName" ) ) )
{
return;
}
if ( name.isEmpty() && !m_fullName.isEmpty() )
{
if ( !m_customHostName )
@ -837,11 +842,7 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
updateGSAutoLogin( doAutoLogin(), loginName() );
checkReady();
loadPresets( configurationMap,
{
"fullname",
"loginname",
} );
ApplyPresets( *this, configurationMap ).apply( "fullName" ).apply( "loginName" );
}
void

Loading…
Cancel
Save