[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.
This commit is contained in:
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,33 +34,6 @@ Config::Config( QObject* parent )
|
||||
|
||||
Config::~Config() {}
|
||||
|
||||
void
|
||||
Config::loadPresets( const QVariantMap& configurationMap )
|
||||
{
|
||||
const QString key( "presets" );
|
||||
if ( !configurationMap.contains( key ) )
|
||||
{
|
||||
d->m_presets.reset();
|
||||
return;
|
||||
}
|
||||
bool bogus = true;
|
||||
d->m_presets = std::make_unique< Presets >( CalamaresUtils::getSubMap( configurationMap, key, bogus ) );
|
||||
}
|
||||
|
||||
void
|
||||
Config::loadPresets( const QVariantMap& configurationMap, const QStringList& recognizedKeys )
|
||||
{
|
||||
const QString key( "presets" );
|
||||
if ( !configurationMap.contains( key ) )
|
||||
{
|
||||
d->m_presets.reset();
|
||||
return;
|
||||
}
|
||||
bool bogus = true;
|
||||
d->m_presets
|
||||
= std::make_unique< Presets >( CalamaresUtils::getSubMap( configurationMap, key, bogus ), recognizedKeys );
|
||||
}
|
||||
|
||||
bool
|
||||
Config::isEditable( const QString& fieldName ) const
|
||||
{
|
||||
@ -71,9 +45,52 @@ Config::isEditable( const QString& fieldName ) const
|
||||
{
|
||||
return d->m_presets->isEditable( fieldName );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Checking isEditable, but no presets are configured.";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Config::ApplyPresets::ApplyPresets( Calamares::ModuleSystem::Config& c, const QVariantMap& configurationMap )
|
||||
: m_c( c )
|
||||
, m_bogus( true )
|
||||
, m_map( CalamaresUtils::getSubMap( configurationMap, "presets", m_bogus ) )
|
||||
{
|
||||
c.m_unlocked = true;
|
||||
if ( !c.d->m_presets )
|
||||
{
|
||||
c.d->m_presets = std::make_unique< Presets >();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Config::ApplyPresets&
|
||||
Config::ApplyPresets::apply( const char* fieldName )
|
||||
{
|
||||
const auto prop = m_c.property( fieldName );
|
||||
if ( !prop.isValid() )
|
||||
{
|
||||
cWarning() << "Applying invalid property" << fieldName;
|
||||
}
|
||||
else
|
||||
{
|
||||
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 *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…
Reference in New Issue
Block a user