diff --git a/3d-viewer/3d_viewer/3d_viewer_settings.cpp b/3d-viewer/3d_viewer/3d_viewer_settings.cpp
index 7278fa661b..5a2052042f 100644
--- a/3d-viewer/3d_viewer/3d_viewer_settings.cpp
+++ b/3d-viewer/3d_viewer/3d_viewer_settings.cpp
@@ -240,7 +240,7 @@ bool EDA_3D_VIEWER_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
if( aCfg->Read( k_r, &color.r ) &&
aCfg->Read( k_g, &color.g ) && aCfg->Read( k_b, &color.b ) )
{
- ( *this )[PointerFromString( destKey )] = color;
+ Set( destKey, color );
}
};
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index c1e8c8a494..f2d9a2c2b3 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -457,6 +457,7 @@ set( COMMON_SRCS
settings/common_settings.cpp
settings/json_settings.cpp
settings/nested_settings.cpp
+ settings/parameters.cpp
settings/settings_manager.cpp
project/board_project_settings.cpp
diff --git a/common/project/net_settings.cpp b/common/project/net_settings.cpp
index 8272781636..9d91f08bad 100644
--- a/common/project/net_settings.cpp
+++ b/common/project/net_settings.cpp
@@ -18,6 +18,8 @@
* with this program. If not, see .
*/
+#include
+
#include
#include
#include
diff --git a/common/project/project_file.cpp b/common/project/project_file.cpp
index 6a3437ec02..207de1760d 100644
--- a/common/project/project_file.cpp
+++ b/common/project/project_file.cpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -142,7 +143,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
libKey << ++libIndex;
}
- ( *this )[PointerFromString( aDest )] = libs;
+ Set( aDest, libs );
};
aCfg->SetPath( wxT( "/LibeditFrame" ) );
@@ -168,7 +169,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
eqKey << ++eqIdx;
}
- ( *this )[PointerFromString( "cvpcb.equivalence_files" )] = eqs;
+ Set( "cvpcb.equivalence_files", eqs );
}
// All CvPcb params that we want to keep have been migrated above
@@ -194,7 +195,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
libKey << ++libIdx;
}
- ( *this )[PointerFromString( "schematic.legacy_lib_list" )] = libs;
+ Set( "schematic.legacy_lib_list", libs );
}
group_blacklist.insert( wxT( "/eeschema" ) );
@@ -219,7 +220,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
txtKey << ++txtIdx;
}
- ( *this )[PointerFromString( "text_variables" )] = vars;
+ Set( "text_variables", vars );
}
group_blacklist.insert( wxT( "/text_variables" ) );
@@ -273,7 +274,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
key << ++idx;
}
- ( *this )[PointerFromString( bp + "drc_exclusions" )] = exclusions;
+ Set( bp + "drc_exclusions", exclusions );
}
fromLegacy( aCfg, "AllowMicroVias", bp + "rules.allow_microvias" );
@@ -372,7 +373,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
key << ++idx;
}
- ( *this )[PointerFromString( bp + "track_widths" )] = widths;
+ Set( bp + "track_widths", widths );
}
{
@@ -398,7 +399,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
key << ++idx;
}
- ( *this )[PointerFromString( bp + "via_dimensions" )] = vias;
+ Set( bp + "via_dimensions", vias );
}
{
@@ -428,7 +429,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
key << ++idx;
}
- ( *this )[PointerFromString( bp + "diff_pair_dimensions" )] = pairs;
+ Set( bp + "diff_pair_dimensions", pairs );
}
group_blacklist.insert( wxT( "/pcbnew" ) );
@@ -461,7 +462,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
}
}
- ( *this )[PointerFromString( "sheets" )] = arr;
+ Set( "sheets", arr );
aCfg->SetPath( "/" );
@@ -494,8 +495,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
try
{
- nlohmann::json::json_pointer ptr( "/legacy" + aGroup + "/" + key );
- ( *this )[ptr] = val;
+ Set( "legacy." + aGroup + "." + key, val );
}
catch( ... )
{
@@ -543,8 +543,7 @@ bool PROJECT_FILE::SaveToFile( const wxString& aDirectory, bool aForce )
{
wxASSERT( m_project );
- ( *this )[PointerFromString( "meta.filename" )] =
- m_project->GetProjectName() + "." + ProjectFileExtension;
+ Set( "meta.filename", m_project->GetProjectName() + "." + ProjectFileExtension );
return JSON_SETTINGS::SaveToFile( aDirectory, aForce );
}
diff --git a/common/project/project_local_settings.cpp b/common/project/project_local_settings.cpp
index db9d2b2597..095c535f00 100644
--- a/common/project/project_local_settings.cpp
+++ b/common/project/project_local_settings.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
const int projectLocalSettingsVersion = 3;
@@ -230,18 +231,18 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
* LAYER_PADS and LAYER_ZONES added to visibility controls
*/
- nlohmann::json::json_pointer ptr( "/board/visible_items"_json_pointer );
+ std::string ptr( "board.visible_items" );
- if( contains( ptr ) )
+ if( Contains( ptr ) )
{
- if( ( *this )[ptr].is_array() )
+ if( At( ptr ).is_array() )
{
- ( *this )[ptr].push_back( LAYER_PADS );
- ( *this )[ptr].push_back( LAYER_ZONES );
+ At( ptr ).push_back( LAYER_PADS );
+ At( ptr ).push_back( LAYER_ZONES );
}
else
{
- at( "board" ).erase( "visible_items" );
+ At( "board" ).erase( "visible_items" );
}
}
@@ -277,13 +278,13 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
{ 40, 33 }, // LAYER_ZONES
};
- nlohmann::json::json_pointer ptr( "/board/visible_items"_json_pointer );
+ std::string ptr( "board.visible_items" );
- if( contains( ptr ) && at( ptr ).is_array() )
+ if( Contains( ptr ) && At( ptr ).is_array() )
{
nlohmann::json visible = nlohmann::json::array();
- for( const nlohmann::json& val : at( ptr ) )
+ for( const nlohmann::json& val : At( ptr ) )
{
try
{
@@ -300,7 +301,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
}
}
- at( "board" )["visible_items"] = visible;
+ At( "board" )["visible_items"] = visible;
}
return true;
@@ -323,8 +324,7 @@ bool PROJECT_LOCAL_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce
{
wxASSERT( m_project );
- ( *this )[PointerFromString( "meta.filename" )] =
- m_project->GetProjectName() + "." + ProjectLocalSettingsFileExtension;
+ Set( "meta.filename", m_project->GetProjectName() + "." + ProjectLocalSettingsFileExtension );
return JSON_SETTINGS::SaveToFile( aDirectory, aForce );
}
diff --git a/common/settings/app_settings.cpp b/common/settings/app_settings.cpp
index c909a6cb98..e019065201 100644
--- a/common/settings/app_settings.cpp
+++ b/common/settings/app_settings.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -175,7 +176,7 @@ bool APP_SETTINGS_BASE::MigrateFromLegacy( wxConfigBase* aCfg )
js.push_back( i );
}
- ( *this )[PointerFromString( "printing.layers" ) ] = js;
+ Set( "printing.layers", js );
}
ret &= fromLegacy( aCfg, f + "FirstRunShown", "system.first_run_shown" );
@@ -196,7 +197,7 @@ bool APP_SETTINGS_BASE::MigrateFromLegacy( wxConfigBase* aCfg )
js.push_back( file.ToStdString() );
}
- ( *this )[PointerFromString( "system.file_history" )] = js;
+ Set( "system.file_history", js );
}
ret &= migrateWindowConfig( aCfg, f, "window" );
@@ -224,8 +225,8 @@ void APP_SETTINGS_BASE::migrateFindReplace( wxConfigBase* aCfg )
replace_history.push_back( tmp.ToStdString() );
}
- ( *this )[PointerFromString( "find_replace.find_history" )] = find_history;
- ( *this )[PointerFromString( "find_replace.replace_history" )] = replace_history;
+ Set( "find_replace.find_history", find_history );
+ Set( "find_replace.replace_history", replace_history );
}
diff --git a/common/settings/color_settings.cpp b/common/settings/color_settings.cpp
index 597c48163f..62a152837a 100644
--- a/common/settings/color_settings.cpp
+++ b/common/settings/color_settings.cpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -223,7 +224,7 @@ COLOR_SETTINGS::COLOR_SETTINGS( wxString aFilename ) :
// Fix LAYER_VIA_HOLES color - before version 2, this setting had no effect
nlohmann::json::json_pointer ptr( "/board/via_hole");
- ( *this )[ptr] = COLOR4D( 0.5, 0.4, 0, 0.8 ).ToWxString( wxC2S_CSS_SYNTAX );
+ ( *m_internals )[ptr] = COLOR4D( 0.5, 0.4, 0, 0.8 ).ToWxString( wxC2S_CSS_SYNTAX );
return true;
} );
@@ -285,10 +286,7 @@ bool COLOR_SETTINGS::migrateSchema0to1()
return false;
}
- nlohmann::json::json_pointer board( "/board" );
- nlohmann::json::json_pointer fpedit( "/fpedit" );
-
- if( !contains( fpedit ) )
+ if( !Contains( "fpedit" ) )
{
wxLogTrace( traceSettings, "migrateSchema0to1: %s doesn't have fpedit settings; skipping.",
m_filename );
@@ -300,19 +298,18 @@ bool COLOR_SETTINGS::migrateSchema0to1()
COLOR_SETTINGS* fpsettings = m_manager->AddNewColorSettings( filename );
// Start out with a clone
- nlohmann::json::json_pointer root( "" );
- ( *fpsettings )[root] = at( root );
+ fpsettings->Set( "", At( "" ) );
// Footprint editor now just looks at the "board" namespace
- ( *fpsettings )[board] = fpsettings->at( fpedit );
+ fpsettings->Set( "board", fpsettings->At( "fpedit" ) );
- fpsettings->erase( "fpedit" );
+ fpsettings->Internals()->erase( "fpedit" );
fpsettings->Load();
fpsettings->SetName( fpsettings->GetName() + wxS( " " ) + _( "(Footprints)" ) );
m_manager->Save( fpsettings );
// Now we can get rid of our own copy
- erase( "fpedit" );
+ m_internals->erase( "fpedit" );
return true;
}
diff --git a/common/settings/common_settings.cpp b/common/settings/common_settings.cpp
index dc5d48a6c7..e4d2a9e4db 100644
--- a/common/settings/common_settings.cpp
+++ b/common/settings/common_settings.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -300,8 +301,8 @@ bool COMMON_SETTINGS::migrateSchema0to1()
try
{
- mwp = at( mwp_pointer );
- at( nlohmann::json::json_pointer( "/input"_json_pointer ) ).erase( "mousewheel_pan" );
+ mwp = m_internals->at( mwp_pointer );
+ m_internals->At( "input" ).erase( "mousewheel_pan" );
}
catch( ... )
{
@@ -310,19 +311,19 @@ bool COMMON_SETTINGS::migrateSchema0to1()
if( mwp )
{
- ( *this )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = true;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = true;
- ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_SHIFT;
- ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = 0;
- ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = WXK_CONTROL;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_SHIFT;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = 0;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = WXK_CONTROL;
}
else
{
- ( *this )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = false;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = false;
- ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_CONTROL;
- ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = WXK_SHIFT;
- ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = 0;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_CONTROL;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = WXK_SHIFT;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = 0;
}
return true;
@@ -337,8 +338,8 @@ bool COMMON_SETTINGS::migrateSchema1to2()
try
{
- prefer_selection = at( v1_pointer );
- at( nlohmann::json::json_pointer( "/input"_json_pointer ) ).erase( "prefer_select_to_drag" );
+ prefer_selection = m_internals->at( v1_pointer );
+ m_internals->at( nlohmann::json::json_pointer( "/input"_json_pointer ) ).erase( "prefer_select_to_drag" );
}
catch( ... )
{
@@ -346,9 +347,9 @@ bool COMMON_SETTINGS::migrateSchema1to2()
}
if( prefer_selection )
- ( *this )[nlohmann::json::json_pointer( "/input/mouse_left" )] = MOUSE_DRAG_ACTION::SELECT;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/mouse_left" )] = MOUSE_DRAG_ACTION::SELECT;
else
- ( *this )[nlohmann::json::json_pointer( "/input/mouse_left" )] = MOUSE_DRAG_ACTION::DRAG_ANY;
+ ( *m_internals )[nlohmann::json::json_pointer( "/input/mouse_left" )] = MOUSE_DRAG_ACTION::DRAG_ANY;
return true;
}
@@ -374,10 +375,10 @@ bool COMMON_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
auto load_env_vars = [&] () {
wxString key, value;
long index = 0;
- nlohmann::json::json_pointer ptr = PointerFromString( "environment.vars" );
+ nlohmann::json::json_pointer ptr = m_internals->PointerFromString( "environment.vars" );
aCfg->SetPath( "EnvironmentVariables" );
- ( *this )[ptr] = nlohmann::json( {} );
+ ( *m_internals )[ptr] = nlohmann::json( {} );
while( aCfg->GetNextEntry( key, index ) )
{
@@ -394,7 +395,7 @@ bool COMMON_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
ptr.push_back( key.ToStdString() );
wxLogTrace( traceSettings, "Migrate Env: %s=%s", ptr.to_string(), value );
- ( *this )[ptr] = value.ToUTF8();
+ ( *m_internals )[ptr] = value.ToUTF8();
ptr.pop_back();
}
@@ -409,11 +410,10 @@ bool COMMON_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
if( aCfg->Read( "MousewheelPAN", &mousewheel_pan ) && mousewheel_pan )
{
- ( *this )[PointerFromString( "input.horizontal_pan" )] = true;
-
- ( *this )[PointerFromString( "input.scroll_modifier_pan_h" )] = WXK_SHIFT;
- ( *this )[PointerFromString( "input.scroll_modifier_pan_v" )] = 0;
- ( *this )[PointerFromString( "input.scroll_modifier_zoom" )] = WXK_CONTROL;
+ Set( "input.horizontal_pan", true );
+ Set( "input.scroll_modifier_pan_h", static_cast( WXK_SHIFT ) );
+ Set( "input.scroll_modifier_pan_v", 0 );
+ Set( "input.scroll_modifier_zoom", static_cast( WXK_CONTROL ) );
}
ret &= fromLegacy( aCfg, "AutoPAN", "input.auto_pan" );
@@ -423,11 +423,8 @@ bool COMMON_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
ret &= fromLegacy( aCfg, "ZoomNoCenter", "input.center_on_zoom" );
// This was stored inverted in legacy config
- if( ret )
- {
- auto p = PointerFromString( "input.center_on_zoom" );
- ( *this )[p] = !( *this )[p];
- }
+ if( OPT value = Get( "input.center_on_zoom" ) )
+ Set( "input.center_on_zoom", !( *value ) );
ret &= fromLegacy( aCfg, "OpenGLAntialiasingMode", "graphics.opengl_antialiasing_mode" );
ret &= fromLegacy( aCfg, "CairoAntialiasingMode", "graphics.cairo_antialiasing_mode" );
diff --git a/common/settings/json_settings.cpp b/common/settings/json_settings.cpp
index 3ecc3385f9..eba4acfae5 100644
--- a/common/settings/json_settings.cpp
+++ b/common/settings/json_settings.cpp
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -36,13 +37,32 @@
#include
#include
-
const wxChar* const traceSettings = wxT( "KICAD_SETTINGS" );
+
+nlohmann::json::json_pointer JSON_SETTINGS_INTERNALS::PointerFromString( std::string aPath )
+{
+ std::replace( aPath.begin(), aPath.end(), '.', '/' );
+ aPath.insert( 0, "/" );
+
+ nlohmann::json::json_pointer p;
+
+ try
+ {
+ p = nlohmann::json::json_pointer( aPath );
+ }
+ catch( ... )
+ {
+ wxASSERT_MSG( false, wxT( "Invalid pointer path in PointerFromString!" ) );
+ }
+
+ return p;
+}
+
+
JSON_SETTINGS::JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation,
int aSchemaVersion, bool aCreateIfMissing, bool aCreateIfDefault,
bool aWriteFile ) :
- nlohmann::json(),
m_filename( aFilename ),
m_legacy_filename( "" ),
m_location( aLocation ),
@@ -54,9 +74,11 @@ JSON_SETTINGS::JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation,
m_schemaVersion( aSchemaVersion ),
m_manager( nullptr )
{
+ m_internals = std::make_unique();
+
try
{
- ( *this )[PointerFromString( "meta.filename" )] = GetFullFilename();
+ m_internals->SetFromString( "meta.filename", GetFullFilename() );
}
catch( ... )
{
@@ -85,6 +107,30 @@ wxString JSON_SETTINGS::GetFullFilename() const
}
+nlohmann::json& JSON_SETTINGS::At( const std::string& aPath )
+{
+ return m_internals->At( aPath );
+}
+
+
+bool JSON_SETTINGS::Contains( const std::string& aPath ) const
+{
+ return m_internals->contains( JSON_SETTINGS_INTERNALS::PointerFromString( aPath ) );
+}
+
+
+size_t JSON_SETTINGS::Count( const std::string& aPath ) const
+{
+ return m_internals->count( JSON_SETTINGS_INTERNALS::PointerFromString( aPath ) );
+}
+
+
+JSON_SETTINGS_INTERNALS* JSON_SETTINGS::Internals()
+{
+ return m_internals.get();
+}
+
+
void JSON_SETTINGS::Load()
{
for( auto param : m_params )
@@ -105,7 +151,7 @@ void JSON_SETTINGS::Load()
bool JSON_SETTINGS::LoadFromFile( const wxString& aDirectory )
{
// First, load all params to default values
- clear();
+ m_internals->clear();
Load();
bool success = true;
@@ -220,16 +266,17 @@ bool JSON_SETTINGS::LoadFromFile( const wxString& aDirectory )
if( fp )
{
- *static_cast( this ) = nlohmann::json::parse( fp, nullptr,
- /* allow_exceptions = */ true,
- /* ignore_comments = */ true );
+ *static_cast( m_internals.get() ) =
+ nlohmann::json::parse( fp, nullptr,
+ /* allow_exceptions = */ true,
+ /* ignore_comments = */ true );
// If parse succeeds, check if schema migration is required
int filever = -1;
try
{
- filever = at( PointerFromString( "meta.version" ) ).get();
+ filever = m_internals->Get( "meta.version" );
}
catch( ... )
{
@@ -407,7 +454,7 @@ bool JSON_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce )
try
{
std::stringstream buffer;
- buffer << std::setw( 2 ) << *this << std::endl;
+ buffer << std::setw( 2 ) << *m_internals << std::endl;
wxFFileOutputStream fileStream( path.GetFullPath(), "wb" );
@@ -436,13 +483,13 @@ bool JSON_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce )
OPT JSON_SETTINGS::GetJson( const std::string& aPath ) const
{
- nlohmann::json::json_pointer ptr = PointerFromString( aPath );
+ nlohmann::json::json_pointer ptr = m_internals->PointerFromString( aPath );
- if( contains( ptr ) )
+ if( m_internals->contains( ptr ) )
{
try
{
- return OPT{ at( ptr ) };
+ return OPT{ m_internals->at( ptr ) };
}
catch( ... )
{
@@ -453,6 +500,55 @@ OPT JSON_SETTINGS::GetJson( const std::string& aPath ) const
}
+template
+OPT JSON_SETTINGS::Get( const std::string& aPath ) const
+{
+ if( OPT ret = GetJson( aPath ) )
+ {
+ try
+ {
+ return ret->get();
+ }
+ catch( ... )
+ {
+ }
+ }
+
+ return NULLOPT;
+}
+
+
+// Instantiate all required templates here to allow reducing scope of json.hpp
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+template OPT JSON_SETTINGS::Get( const std::string& aPath ) const;
+
+
+template
+void JSON_SETTINGS::Set( const std::string& aPath, ValueType aVal )
+{
+ m_internals->SetFromString( aPath, aVal );
+}
+
+
+// Instantiate all required templates here to allow reducing scope of json.hpp
+template void JSON_SETTINGS::Set( const std::string& aPath, bool aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, double aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, float aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, int aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, unsigned int aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, unsigned long long aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, const char* aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, std::string aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, nlohmann::json aValue );
+template void JSON_SETTINGS::Set( const std::string& aPath, KIGFX::COLOR4D aValue );
+
+
void JSON_SETTINGS::registerMigration( int aOldSchemaVersion, int aNewSchemaVersion,
std::function aMigrator )
{
@@ -464,7 +560,7 @@ void JSON_SETTINGS::registerMigration( int aOldSchemaVersion, int aNewSchemaVers
bool JSON_SETTINGS::Migrate()
{
- int filever = at( PointerFromString( "meta.version" ) ).get();
+ int filever = m_internals->Get( "meta.version" );
while( filever < m_schemaVersion )
{
@@ -482,7 +578,7 @@ bool JSON_SETTINGS::Migrate()
wxLogTrace( traceSettings, "Migrated %s from %d to %d", typeid( *this ).name(),
filever, pair.first );
filever = pair.first;
- ( *this )[PointerFromString( "meta.version" )] = filever;
+ m_internals->At( "meta.version" ) = filever;
}
else
{
@@ -504,30 +600,10 @@ bool JSON_SETTINGS::MigrateFromLegacy( wxConfigBase* aLegacyConfig )
}
-nlohmann::json::json_pointer JSON_SETTINGS::PointerFromString( std::string aPath )
-{
- std::replace( aPath.begin(), aPath.end(), '.', '/' );
- aPath.insert( 0, "/" );
-
- nlohmann::json::json_pointer p;
-
- try
- {
- p = nlohmann::json::json_pointer( aPath );
- }
- catch( ... )
- {
- wxASSERT_MSG( false, wxT( "Invalid pointer path in PointerFromString!" ) );
- }
-
- return p;
-}
-
-
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
wxString& aTarget )
{
- nlohmann::json::json_pointer ptr = PointerFromString( aPath );
+ nlohmann::json::json_pointer ptr = JSON_SETTINGS_INTERNALS::PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_string() )
{
@@ -542,7 +618,7 @@ bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string&
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
bool& aTarget )
{
- nlohmann::json::json_pointer ptr = PointerFromString( aPath );
+ nlohmann::json::json_pointer ptr = JSON_SETTINGS_INTERNALS::PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_boolean() )
{
@@ -557,7 +633,7 @@ bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string&
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
int& aTarget )
{
- nlohmann::json::json_pointer ptr = PointerFromString( aPath );
+ nlohmann::json::json_pointer ptr = JSON_SETTINGS_INTERNALS::PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_number_integer() )
{
@@ -572,7 +648,7 @@ bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string&
bool JSON_SETTINGS::SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
unsigned int& aTarget )
{
- nlohmann::json::json_pointer ptr = PointerFromString( aPath );
+ nlohmann::json::json_pointer ptr = JSON_SETTINGS_INTERNALS::PointerFromString( aPath );
if( aObj.contains( ptr ) && aObj.at( ptr ).is_number_unsigned() )
{
@@ -594,7 +670,7 @@ bool JSON_SETTINGS::fromLegacy( wxConfigBase* aConfig, const std::string& aKey,
{
try
{
- ( *this )[PointerFromString( aDest )] = val;
+ ( *m_internals )[aDest] = val;
}
catch( ... )
{
@@ -630,7 +706,7 @@ bool JSON_SETTINGS::fromLegacyString( wxConfigBase* aConfig, const std::string&
{
try
{
- ( *this )[PointerFromString( aDest )] = str.ToUTF8();
+ ( *m_internals )[aDest] = str.ToUTF8();
}
catch( ... )
{
@@ -658,7 +734,7 @@ bool JSON_SETTINGS::fromLegacyColor( wxConfigBase* aConfig, const std::string& a
try
{
nlohmann::json js = nlohmann::json::array( { color.r, color.g, color.b, color.a } );
- ( *this )[PointerFromString( aDest )] = js;
+ ( *m_internals )[aDest] = js;
}
catch( ... )
{
@@ -714,7 +790,7 @@ template<> OPT JSON_SETTINGS::Get( const std::string& aPath ) const
template<> void JSON_SETTINGS::Set( const std::string& aPath, wxString aVal )
{
- ( *this )[PointerFromString( std::move( aPath ) ) ] = aVal.ToUTF8();
+ ( *m_internals )[aPath] = aVal.ToUTF8();
}
// Specializations to allow directly reading/writing wxStrings from JSON
diff --git a/common/settings/nested_settings.cpp b/common/settings/nested_settings.cpp
index 392be8ddde..1cc049d425 100644
--- a/common/settings/nested_settings.cpp
+++ b/common/settings/nested_settings.cpp
@@ -20,6 +20,7 @@
#include
+#include
#include
NESTED_SETTINGS::NESTED_SETTINGS( const std::string& aName, int aVersion, JSON_SETTINGS* aParent,
@@ -40,18 +41,18 @@ NESTED_SETTINGS::~NESTED_SETTINGS()
bool NESTED_SETTINGS::LoadFromFile( const wxString& aDirectory )
{
- clear();
+ m_internals->clear();
bool success = false;
if( m_parent )
{
- nlohmann::json::json_pointer ptr = PointerFromString( m_path );
+ nlohmann::json::json_pointer ptr = m_internals->PointerFromString( m_path );
- if( m_parent->contains( ptr ) )
+ if( m_parent->m_internals->contains( ptr ) )
{
try
{
- update( ( *m_parent )[ptr] );
+ m_internals->update( ( *m_parent->m_internals )[ptr] );
wxLogTrace( traceSettings, "Loaded NESTED_SETTINGS %s", GetFilename() );
@@ -71,7 +72,7 @@ bool NESTED_SETTINGS::LoadFromFile( const wxString& aDirectory )
try
{
- filever = at( PointerFromString( "meta.version" ) ).get();
+ filever = m_internals->Get( "meta.version" );
}
catch( ... )
{
@@ -118,8 +119,9 @@ bool NESTED_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce )
try
{
- nlohmann::json patch =
- nlohmann::json::diff( *this, ( *m_parent )[PointerFromString( m_path )] );
+ nlohmann::json patch = nlohmann::json::diff( *m_internals,
+ m_parent->m_internals->Get( m_path ) );
+
modified |= !patch.empty();
}
catch( ... )
@@ -132,7 +134,7 @@ bool NESTED_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce )
try
{
- ( *m_parent )[PointerFromString( m_path ) ].update( *this );
+ m_parent->m_internals->At( m_path ).update( *m_internals );
wxLogTrace( traceSettings, "Stored NESTED_SETTINGS %s with schema %d",
GetFilename(), m_schemaVersion );
diff --git a/common/settings/parameters.cpp b/common/settings/parameters.cpp
new file mode 100644
index 0000000000..c00c02967f
--- /dev/null
+++ b/common/settings/parameters.cpp
@@ -0,0 +1,290 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2021 Jon Evans
+ * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see .
+ */
+
+#include
+
+#include
+
+#include
+#include
+#include
+
+
+template
+void PARAM_LAMBDA::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const
+{
+ if( m_readOnly )
+ return;
+
+ if( std::is_same::value )
+ {
+ if( OPT optval = aSettings->GetJson( m_path ) )
+ m_setter( *optval );
+ else
+ m_setter( m_default );
+ }
+ else
+ {
+ if( OPT optval = aSettings->Get( m_path ) )
+ m_setter( *optval );
+ else
+ m_setter( m_default );
+ }
+}
+
+
+template
+bool PARAM_LAMBDA::MatchesFile( JSON_SETTINGS* aSettings ) const
+{
+ if( std::is_same::value )
+ {
+ if( OPT optval = aSettings->GetJson( m_path ) )
+ return *optval == m_getter();
+ }
+ else
+ {
+ if( OPT optval = aSettings->Get( m_path ) )
+ return *optval == m_getter();
+ }
+
+ // Not in file
+ return false;
+}
+
+
+// Instantiate all required templates here to allow reducing scope of json.hpp
+template class PARAM_LAMBDA;
+template class PARAM_LAMBDA;
+template class PARAM_LAMBDA;
+template class PARAM_LAMBDA;
+
+
+template
+void PARAM_LIST::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const
+{
+ if( m_readOnly )
+ return;
+
+ if( OPT js = aSettings->GetJson( m_path ) )
+ {
+ std::vector val;
+
+ if( js->is_array() )
+ {
+ for( const auto& el : js->items() )
+ val.push_back( el.value().get() );
+ }
+
+ *m_ptr = val;
+ }
+ else if( aResetIfMissing )
+ *m_ptr = m_default;
+}
+
+
+template
+void PARAM_LIST::Store( JSON_SETTINGS* aSettings ) const
+{
+ nlohmann::json js = nlohmann::json::array();
+
+ for( const auto& el : *m_ptr )
+ js.push_back( el );
+
+ aSettings->Set( m_path, js );
+}
+
+
+template
+bool PARAM_LIST::MatchesFile( JSON_SETTINGS* aSettings ) const
+{
+ if( OPT js = aSettings->GetJson( m_path ) )
+ {
+ if( js->is_array() )
+ {
+ std::vector val;
+
+ for( const auto& el : js->items() )
+ val.emplace_back( el.value().get() );
+
+ return val == *m_ptr;
+ }
+ }
+
+ return false;
+}
+
+
+template class PARAM_LIST;
+template class PARAM_LIST;
+template class PARAM_LIST;
+template class PARAM_LIST;
+template class PARAM_LIST;
+
+
+void PARAM_PATH_LIST::Store( JSON_SETTINGS* aSettings ) const
+{
+ nlohmann::json js = nlohmann::json::array();
+
+ for( const auto& el : *m_ptr )
+ js.push_back( toFileFormat( el ) );
+
+ aSettings->Set( m_path, js );
+}
+
+
+bool PARAM_PATH_LIST::MatchesFile( JSON_SETTINGS* aSettings ) const
+{
+ if( OPT js = aSettings->GetJson( m_path ) )
+ {
+ if( js->is_array() )
+ {
+ std::vector val;
+
+ for( const auto& el : js->items() )
+ val.emplace_back( fromFileFormat( el.value().get() ) );
+
+ return val == *m_ptr;
+ }
+ }
+
+ return false;
+}
+
+
+template
+void PARAM_MAP::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const
+{
+ if( m_readOnly )
+ return;
+
+ if( OPT js = aSettings->GetJson( m_path ) )
+ {
+ if( js->is_object() )
+ {
+ m_ptr->clear();
+
+ for( const auto& el : js->items() )
+ ( *m_ptr )[el.key()] = el.value().get();
+ }
+ }
+ else if( aResetIfMissing )
+ *m_ptr = m_default;
+}
+
+
+template
+void PARAM_MAP::Store( JSON_SETTINGS* aSettings ) const
+{
+ nlohmann::json js( {} );
+
+ for( const auto& el : *m_ptr )
+ js[el.first] = el.second;
+
+ aSettings->Set( m_path, js );
+}
+
+
+template
+bool PARAM_MAP::MatchesFile( JSON_SETTINGS* aSettings ) const
+{
+ if( OPT js = aSettings->GetJson( m_path ) )
+ {
+ if( js->is_object() )
+ {
+ if( m_ptr->size() != js->size() )
+ return false;
+
+ std::map val;
+
+ for( const auto& el : js->items() )
+ val[el.key()] = el.value().get();
+
+ return val == *m_ptr;
+ }
+ }
+
+ return false;
+}
+
+
+template class PARAM_MAP;
+template class PARAM_MAP;
+template class PARAM_MAP;
+
+
+void PARAM_WXSTRING_MAP::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const
+{
+ if( m_readOnly )
+ return;
+
+ if( OPT js = aSettings->GetJson( m_path ) )
+ {
+ if( js->is_object() )
+ {
+ m_ptr->clear();
+
+ for( const auto& el : js->items() )
+ {
+ ( *m_ptr )[wxString( el.key().c_str(), wxConvUTF8 )] = el.value().get();
+ }
+ }
+ }
+ else if( aResetIfMissing )
+ *m_ptr = m_default;
+}
+
+
+void PARAM_WXSTRING_MAP::Store( JSON_SETTINGS* aSettings ) const
+{
+ nlohmann::json js( {} );
+
+ for( const auto& el : *m_ptr )
+ {
+ std::string key( el.first.ToUTF8() );
+ js[key] = el.second;
+ }
+
+ aSettings->Set( m_path, js );
+}
+
+
+bool PARAM_WXSTRING_MAP::MatchesFile( JSON_SETTINGS* aSettings ) const
+{
+ if( OPT js = aSettings->GetJson( m_path ) )
+ {
+ if( js->is_object() )
+ {
+ if( m_ptr->size() != js->size() )
+ return false;
+
+ std::map val;
+
+ for( const auto& el : js->items() )
+ {
+ wxString key( el.key().c_str(), wxConvUTF8 );
+ val[key] = el.value().get();
+ }
+
+ return val == *m_ptr;
+ }
+ }
+
+ return false;
+}
diff --git a/common/settings/settings_manager.cpp b/common/settings/settings_manager.cpp
index 2b584b3ad2..a2a2dd9d75 100644
--- a/common/settings/settings_manager.cpp
+++ b/common/settings/settings_manager.cpp
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
@@ -325,7 +326,8 @@ void SETTINGS_MANAGER::SaveColorSettings( COLOR_SETTINGS* aSettings, const std::
}
) != m_color_settings.end() );
- nlohmann::json::json_pointer ptr = JSON_SETTINGS::PointerFromString( aNamespace );
+ if( aSettings->IsReadOnly() )
+ return;
if( !aSettings->Store() )
{
@@ -334,17 +336,17 @@ void SETTINGS_MANAGER::SaveColorSettings( COLOR_SETTINGS* aSettings, const std::
return;
}
- wxASSERT( aSettings->contains( ptr ) );
+ wxASSERT( aSettings->Contains( aNamespace ) );
wxLogTrace( traceSettings, "Saving color scheme %s, preserving %s", aSettings->GetFilename(),
- aNamespace );
+ aNamespace );
- nlohmann::json backup = aSettings->at( ptr );
+ nlohmann::json backup = aSettings->At( aNamespace );
wxString path = GetColorSettingsPath();
aSettings->LoadFromFile( path );
- ( *aSettings )[ptr].update( backup );
+ ( *aSettings->Internals() )[aNamespace].update( backup );
aSettings->Load();
aSettings->SaveToFile( path, true );
diff --git a/eeschema/eeschema_settings.cpp b/eeschema/eeschema_settings.cpp
index d6cdf20d5e..0c63ab694d 100644
--- a/eeschema/eeschema_settings.cpp
+++ b/eeschema/eeschema_settings.cpp
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -405,16 +406,16 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
// Now modify the loaded grid selection, because in earlier versions the grids index was shared
// between all applications and started at 1000 mils. There is a 4-position offset between
// this index and the possible eeschema grids list that we have to subtract.
- nlohmann::json::json_pointer gridSizePtr = PointerFromString( "window.grid.last_size" );
+ std::string gridSizePtr = "window.grid.last_size";
- try
+ if( OPT currentSize = Get( gridSizePtr ) )
{
- ( *this )[gridSizePtr] = ( *this )[gridSizePtr].get() - 4;
+ Set( gridSizePtr, *currentSize - 4 );
}
- catch( ... )
+ else
{
// Otherwise, default grid size should be 50 mils; index 1
- ( *this )[gridSizePtr] = 1;
+ Set( gridSizePtr, 1 );
}
ret &= fromLegacy( aCfg, "FootprintPreview", "appearance.footprint_preview" );
@@ -497,8 +498,8 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
}
}
- ( *this )[PointerFromString( "netlist.custom_command_titles" )] = js_title;
- ( *this )[PointerFromString( "netlist.custom_command_paths" )] = js_cmd;
+ Set( "netlist.custom_command_titles", js_title );
+ Set( "netlist.custom_command_paths", js_cmd );
}
{
@@ -518,11 +519,11 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
if( aCfg->Read( key, &value ) )
{
std::string key_utf( key.ToUTF8() );
- js[PointerFromString( key_utf )] = value;
+ js[JSON_SETTINGS_INTERNALS::PointerFromString( key_utf )] = value;
}
}
- ( *this )[PointerFromString( "field_editor.fields_show" ) ] = js;
+ Set( "field_editor.fields_show", js );
aCfg->SetPath( "../GroupBy" );
@@ -531,11 +532,11 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
if( aCfg->Read( key, &value ) )
{
std::string key_utf( key.ToUTF8() );
- js[PointerFromString( key_utf )] = value;
+ js[JSON_SETTINGS_INTERNALS::PointerFromString( key_utf )] = value;
}
}
- ( *this )[PointerFromString( "field_editor.fields_group_by" ) ] = js;
+ Set( "field_editor.fields_group_by", js );
aCfg->SetPath( "../.." );
}
@@ -628,7 +629,7 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
Pgm().GetSettingsManager().SaveColorSettings( cs, "schematic" );
- ( *this )[PointerFromString( "appearance.color_theme" )] = cs->GetFilename();
+ Set( "appearance.color_theme", cs->GetFilename() );
// LibEdit settings were stored with eeschema. If eeschema is the first app to run,
// we need to migrate the LibEdit settings here
@@ -668,12 +669,10 @@ std::vector EESCHEMA_SETTINGS::DefaultBo
bool EESCHEMA_SETTINGS::migrateBomSettings()
{
- nlohmann::json::json_pointer ptr = PointerFromString( "bom.plugins" );
-
- if( !contains( ptr ) )
+ if( !Contains( "bom.plugins" ) )
return false;
- wxString list = at( ptr ).get();
+ wxString list = Get( "bom.plugins" ).value();
BOM_CFG_PARSER cfg_parser( &m_BomPanel.plugins, TO_UTF8( list ), wxT( "plugins" ) );
@@ -687,7 +686,7 @@ bool EESCHEMA_SETTINGS::migrateBomSettings()
}
// Parser will have loaded up our array, let's dump it out to JSON
- at( ptr ) = bomSettingsToJson();
+ At( "bom.plugins" ) = bomSettingsToJson();
return true;
}
diff --git a/eeschema/erc_settings.cpp b/eeschema/erc_settings.cpp
index b3a9275a56..bc14d5d6d9 100644
--- a/eeschema/erc_settings.cpp
+++ b/eeschema/erc_settings.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
diff --git a/eeschema/schematic_settings.cpp b/eeschema/schematic_settings.cpp
index 6ae5b1a0cb..07c6dd9d55 100644
--- a/eeschema/schematic_settings.cpp
+++ b/eeschema/schematic_settings.cpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
diff --git a/eeschema/symbol_editor/symbol_editor_settings.cpp b/eeschema/symbol_editor/symbol_editor_settings.cpp
index dec5c5b9c1..008ad61481 100644
--- a/eeschema/symbol_editor/symbol_editor_settings.cpp
+++ b/eeschema/symbol_editor/symbol_editor_settings.cpp
@@ -92,16 +92,16 @@ bool SYMBOL_EDITOR_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
// Now modify the loaded grid selection, because in earlier versions the grids index was shared
// between all applications and started at 1000 mils. There is a 4-position offset between
// this index and the possible eeschema grids list that we have to subtract.
- nlohmann::json::json_pointer gridSizePtr = PointerFromString( "window.grid.last_size" );
+ std::string gridSizePtr = "window.grid.last_size";
- try
+ if( OPT currentSize = Get( gridSizePtr ) )
{
- ( *this )[gridSizePtr] = ( *this )[gridSizePtr].get() - 4;
+ Set( gridSizePtr, *currentSize - 4 );
}
- catch( ... )
+ else
{
// Otherwise, default grid size should be 50 mils; index 1
- ( *this )[gridSizePtr] = 1;
+ Set( gridSizePtr, 1 );
}
ret &= fromLegacy( aCfg, "DefaultWireWidth", "defaults.line_width" );
diff --git a/gerbview/gerbview_settings.cpp b/gerbview/gerbview_settings.cpp
index 4e781b8ed5..d1cfa51d87 100644
--- a/gerbview/gerbview_settings.cpp
+++ b/gerbview/gerbview_settings.cpp
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -99,7 +100,7 @@ bool GERBVIEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
aCfg->SetPath( ".." );
- ( *this )[PointerFromString( aDest )] = js;
+ Set( aDest, js );
};
migrate_files( "drl_files", "system.drill_file_history" );
@@ -109,15 +110,14 @@ bool GERBVIEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
{
wxString key;
int value = 0;
- nlohmann::json::json_pointer ptr = PointerFromString( "gerber_to_pcb_layers" );
- ( *this )[ptr] = nlohmann::json::array();
+ At( "gerber_to_pcb_layers" ) = nlohmann::json::array();
for( int i = 0; i < GERBER_DRAWLAYERS_COUNT; i++ )
{
key.Printf( "GbrLyr%dToPcb", i );
aCfg->Read( key, &value, UNSELECTED_LAYER );
- ( *this )[ptr].emplace_back( value );
+ At( "gerber_to_pcb_layers" ).emplace_back( value );
}
}
@@ -147,7 +147,7 @@ bool GERBVIEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
Pgm().GetSettingsManager().SaveColorSettings( cs, "gerbview" );
- ( *this )[PointerFromString( "appearance.color_theme" )] = cs->GetFilename();
+ Set( "appearance.color_theme", cs->GetFilename() );
return ret;
}
diff --git a/include/project/board_project_settings.h b/include/project/board_project_settings.h
index 20df87c080..666ac667ae 100644
--- a/include/project/board_project_settings.h
+++ b/include/project/board_project_settings.h
@@ -24,6 +24,9 @@
#include
#include
+// Can be removed by refactoring PARAM_LAYER_PRESET
+#include
+
/**
* This file contains data structures that are saved in the project file or project local settings
* file that are specific to PcbNew. This is done so that these structures are available in common.
diff --git a/include/settings/color_settings.h b/include/settings/color_settings.h
index 1774a744b0..e87f72fdd7 100644
--- a/include/settings/color_settings.h
+++ b/include/settings/color_settings.h
@@ -21,6 +21,8 @@
#ifndef _COLOR_SETTINGS_H
#define _COLOR_SETTINGS_H
+#include
+
#include
#include
#include
diff --git a/include/settings/json_settings.h b/include/settings/json_settings.h
index 97c4006a6b..d06a71d14a 100644
--- a/include/settings/json_settings.h
+++ b/include/settings/json_settings.h
@@ -23,11 +23,11 @@
#include
-#include
#include
#include
#include
+#include
class wxConfigBase;
class NESTED_SETTINGS;
@@ -52,9 +52,14 @@ enum class SETTINGS_LOC {
};
-class JSON_SETTINGS : public nlohmann::json
+/// pimpl to allow hiding json.hpp
+class JSON_SETTINGS_INTERNALS;
+
+class JSON_SETTINGS
{
public:
+ friend class NESTED_SETTINGS;
+
JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation, int aSchemaVersion ) :
JSON_SETTINGS( aFilename, aLocation, aSchemaVersion, true, true, true ) {}
@@ -76,6 +81,17 @@ public:
bool IsReadOnly() const { return !m_writeFile; }
void SetReadOnly( bool aReadOnly ) { m_writeFile = !aReadOnly; }
+ /**
+ * Wrappers for the underlying JSON API so that most consumers don't need json.hpp
+ * All of these functions take a string that is passed to PointerFromString internally.
+ */
+
+ nlohmann::json& At( const std::string& aPath );
+ bool Contains( const std::string& aPath ) const;
+ size_t Count( const std::string& aPath ) const;
+
+ JSON_SETTINGS_INTERNALS* Internals();
+
/**
* Updates the parameters of this object based on the current JSON document contents
*/
@@ -130,21 +146,7 @@ c * @return true if the file was saved
* @return a value from within this document
*/
template
- OPT Get( const std::string& aPath ) const
- {
- if( OPT ret = GetJson( aPath ) )
- {
- try
- {
- return ret->get();
- }
- catch( ... )
- {
- }
- }
-
- return NULLOPT;
- }
+ OPT Get( const std::string& aPath ) const;
/**
* Stores a value into the JSON document
@@ -154,10 +156,7 @@ c * @return true if the file was saved
* @param aVal is the value to store
*/
template
- void Set( const std::string& aPath, ValueType aVal )
- {
- ( *this )[PointerFromString( aPath ) ] = aVal;
- }
+ void Set( const std::string& aPath, ValueType aVal );
/**
* Migrates the schema of this settings from the version in the file to the latest version
@@ -199,13 +198,6 @@ c * @return true if the file was saved
m_manager = aManager;
}
- /**
- * Builds a JSON pointer based on a given string
- * @param aPath is the path in the form "key1.key2.key3"
- * @return a JSON pointer that can be used to index into a JSON object
- */
- static nlohmann::json::json_pointer PointerFromString( std::string aPath );
-
/**
* Sets the given string if the given key/path is present
* @param aObj is the source object
@@ -329,11 +321,10 @@ protected:
/// A pointer to the settings manager managing this file (may be null)
SETTINGS_MANAGER* m_manager;
- /// A list of JSON pointers that are preserved during a read-update-write to disk
- std::vector m_preserved_paths;
-
/// A map of starting schema version to a pair of
std::map>> m_migrators;
+
+ std::unique_ptr m_internals;
};
// Specializations to allow conversion between wxString and std::string via JSON_SETTINGS API
diff --git a/include/settings/json_settings_internals.h b/include/settings/json_settings_internals.h
new file mode 100644
index 0000000000..1d8ef6faef
--- /dev/null
+++ b/include/settings/json_settings_internals.h
@@ -0,0 +1,67 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2021 Jon Evans
+ * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see .
+ */
+
+#ifndef KICAD_JSON_SETTINGS_INTERNALS_H
+#define KICAD_JSON_SETTINGS_INTERNALS_H
+
+// This is a pretty heavy file. Try to use json_fwd.hpp most places.
+#include
+
+class JSON_SETTINGS_INTERNALS : public nlohmann::json
+{
+ friend class JSON_SETTINGS;
+
+public:
+ JSON_SETTINGS_INTERNALS() :
+ nlohmann::json()
+ {}
+
+ /**
+ * Builds a JSON pointer based on a given string
+ * @param aPath is the path in the form "key1.key2.key3"
+ * @return a JSON pointer that can be used to index into a JSON object
+ */
+ static nlohmann::json::json_pointer PointerFromString( std::string aPath );
+
+ template
+ void SetFromString( const std::string& aPath, ValueType aVal )
+ {
+ // Calls the overload below, which will convert from dotted string to JSON pointer
+ ( *this )[aPath] = aVal;
+ }
+
+ template
+ ValueType Get( const std::string& aPath ) const
+ {
+ return at( PointerFromString( aPath ) ).get();
+ }
+
+ nlohmann::json& At( const std::string& aPath )
+ {
+ return at( PointerFromString( aPath ) );
+ }
+
+ nlohmann::json& operator[]( const std::string& aPath )
+ {
+ return nlohmann::json::operator[]( PointerFromString( aPath ) );
+ }
+};
+
+#endif // KICAD_JSON_SETTINGS_INTERNALS_H
diff --git a/include/settings/parameters.h b/include/settings/parameters.h
index 19c7a26812..644c0ce7c9 100644
--- a/include/settings/parameters.h
+++ b/include/settings/parameters.h
@@ -305,26 +305,7 @@ public:
m_setter( aSetter )
{ }
- void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
- {
- if( m_readOnly )
- return;
-
- if( std::is_same::value )
- {
- if( OPT optval = aSettings->GetJson( m_path ) )
- m_setter( *optval );
- else
- m_setter( m_default );
- }
- else
- {
- if( OPT optval = aSettings->Get( m_path ) )
- m_setter( *optval );
- else
- m_setter( m_default );
- }
- }
+ void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override;
void Store( JSON_SETTINGS* aSettings ) const override
{
@@ -352,22 +333,7 @@ public:
return m_getter() == m_default;
}
- bool MatchesFile( JSON_SETTINGS* aSettings ) const override
- {
- if( std::is_same::value )
- {
- if( OPT optval = aSettings->GetJson( m_path ) )
- return *optval == m_getter();
- }
- else
- {
- if( OPT optval = aSettings->Get( m_path ) )
- return *optval == m_getter();
- }
-
- // Not in file
- return false;
- }
+ bool MatchesFile( JSON_SETTINGS* aSettings ) const override;
private:
ValueType m_default;
@@ -488,36 +454,9 @@ public:
m_default( aDefault )
{ }
- void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
- {
- if( m_readOnly )
- return;
+ void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override;
- if( OPT js = aSettings->GetJson( m_path ) )
- {
- std::vector val;
-
- if( js->is_array() )
- {
- for( const auto& el : js->items() )
- val.push_back( el.value().get() );
- }
-
- *m_ptr = val;
- }
- else if( aResetIfMissing )
- *m_ptr = m_default;
- }
-
- void Store( JSON_SETTINGS* aSettings) const override
- {
- nlohmann::json js = nlohmann::json::array();
-
- for( const auto& el : *m_ptr )
- js.push_back( el );
-
- aSettings->Set( m_path, js );
- }
+ void Store( JSON_SETTINGS* aSettings) const override;
void SetDefault() override
{
@@ -529,23 +468,7 @@ public:
return *m_ptr == m_default;
}
- bool MatchesFile( JSON_SETTINGS* aSettings ) const override
- {
- if( OPT js = aSettings->GetJson( m_path ) )
- {
- if( js->is_array() )
- {
- std::vector