95            [&]() -> nlohmann::json
 
   97                nlohmann::json ret = nlohmann::json::array();
 
  100                    ret.push_back( libName );
 
  104            [&]( 
const nlohmann::json& aJson )
 
  106                if( aJson.empty() || !aJson.is_array() )
 
  111                for( 
const nlohmann::json& entry : aJson )
 
  116            [&]() -> nlohmann::json
 
  118                nlohmann::json ret = nlohmann::json::object();
 
  122                    nlohmann::json members = nlohmann::json::array();
 
  124                    for( 
const wxString& member : alias.second )
 
  125                        members.push_back( member );
 
  127                    ret[ alias.first.ToStdString() ] = members;
 
  132            [&]( 
const nlohmann::json& aJson )
 
  134                if( aJson.empty() || !aJson.is_object() )
 
  139                for( 
auto it = aJson.begin(); it != aJson.end(); ++it )
 
  141                    const nlohmann::json& membersJson = it.value();
 
  143                    if( !membersJson.is_array() )
 
  146                    std::vector<wxString> members;
 
  148                    for( 
const nlohmann::json& entry : membersJson )
 
  150                        if( entry.is_string() )
 
  151                            members.push_back( entry.get<wxString>() );
 
  154                    m_BusAliases.emplace( wxString::FromUTF8( it.key().c_str() ), std::move( members ) );
 
  158    m_NetSettings = std::make_shared<NET_SETTINGS>( 
this, 
"net_settings" );
 
  161            std::make_shared<COMPONENT_CLASS_SETTINGS>( 
this, 
"component_class_settings" );
 
 
  196    auto p( 
"/board/layer_presets"_json_pointer );
 
  203    for( nlohmann::json& entry : presets )
 
 
  214    auto p( 
"/board/layer_presets"_json_pointer );
 
  221    for( nlohmann::json& entry : presets )
 
 
  236    std::set<wxString> group_blacklist;
 
  243    auto loadPinnedLibs =
 
  244            [&]( 
const std::string& aDest )
 
  247                wxString libKey   = wxT( 
"PinnedItems" );
 
  250                nlohmann::json libs = nlohmann::json::array();
 
  252                while( aCfg->Read( libKey, &str ) )
 
  254                    libs.push_back( str );
 
  256                    aCfg->DeleteEntry( libKey, 
true );
 
  258                    libKey = wxT( 
"PinnedItems" );
 
  259                    libKey << ++libIndex;
 
  265    aCfg->SetPath( wxT( 
"/LibeditFrame" ) );
 
  266    loadPinnedLibs( 
"libraries.pinned_symbol_libs" );
 
  268    aCfg->SetPath( wxT( 
"/ModEditFrame" ) );
 
  269    loadPinnedLibs( 
"libraries.pinned_footprint_libs" );
 
  271    aCfg->SetPath( wxT( 
"/cvpcb/equfiles" ) );
 
  275        wxString eqKey = wxT( 
"EquName" );
 
  278        nlohmann::json eqs = nlohmann::json::array();
 
  280        while( aCfg->Read( eqKey, &str ) )
 
  282            eqs.push_back( str );
 
  284            eqKey = wxT( 
"EquName" );
 
  288        Set( 
"cvpcb.equivalence_files", eqs );
 
  292    group_blacklist.insert( wxT( 
"/cvpcb" ) );
 
  294    aCfg->SetPath( wxT( 
"/eeschema" ) );
 
  297    aCfg->SetPath( wxT( 
"/eeschema/libraries" ) );
 
  301        wxString libKey = wxT( 
"LibName" );
 
  304        nlohmann::json libs = nlohmann::json::array();
 
  306        while( aCfg->Read( libKey, &str ) )
 
  308            libs.push_back( str );
 
  310            libKey = wxT( 
"LibName" );
 
  314        Set( 
"schematic.legacy_lib_list", libs );
 
  317    group_blacklist.insert( wxT( 
"/eeschema" ) );
 
  319    aCfg->SetPath( wxT( 
"/text_variables" ) );
 
  326        nlohmann::json vars = nlohmann::json();
 
  328        while( aCfg->Read( txtKey, &str ) )
 
  330            wxArrayString tokens = wxSplit( str, 
':' );
 
  332            if( tokens.size() == 2 )
 
  333                vars[ tokens[0].ToStdString() ] = tokens[1];
 
  339        Set( 
"text_variables", vars );
 
  342    group_blacklist.insert( wxT( 
"/text_variables" ) );
 
  344    aCfg->SetPath( wxT( 
"/schematic_editor" ) );
 
  346    fromLegacyString( aCfg, 
"PageLayoutDescrFile",     
"schematic.page_layout_descr_file" );
 
  349    fromLegacy<bool>( aCfg, 
"SpiceAjustPassiveValues", 
"schematic.spice_adjust_passive_values" );
 
  350    fromLegacy<int>(  aCfg, 
"SubpartIdSeparator",      
"schematic.subpart_id_separator" );
 
  351    fromLegacy<int>(  aCfg, 
"SubpartFirstId",          
"schematic.subpart_first_id" );
 
  353    fromLegacy<int>( aCfg, 
"LineThickness",            
"schematic.drawing.default_line_thickness" );
 
  354    fromLegacy<int>( aCfg, 
"WireThickness",            
"schematic.drawing.default_wire_thickness" );
 
  355    fromLegacy<int>( aCfg, 
"BusThickness",             
"schematic.drawing.default_bus_thickness" );
 
  356    fromLegacy<int>( aCfg, 
"LabSize",                  
"schematic.drawing.default_text_size" );
 
  358    if( !
fromLegacy<int>( aCfg, 
"PinSymbolSize",       
"schematic.drawing.pin_symbol_size" ) )
 
  361        Set( 
"schematic.drawing.pin_symbol_size", 0 );
 
  364    fromLegacy<int>( aCfg, 
"JunctionSize",             
"schematic.drawing.default_junction_size" );
 
  366    fromLegacyString( aCfg, 
"FieldNameTemplates",    
"schematic.drawing.field_names" );
 
  368    if( !
fromLegacy<double>( aCfg, 
"TextOffsetRatio",  
"schematic.drawing.text_offset_ratio" ) )
 
  371        Set( 
"schematic.drawing.text_offset_ratio", 0.08 );
 
  372        Set( 
"schematic.drawing.label_size_ratio", 0.25 );
 
  376    group_blacklist.insert( wxT( 
"/schematic_editor" ) );
 
  378    aCfg->SetPath( wxT( 
"/pcbnew" ) );
 
  380    fromLegacyString( aCfg, 
"PageLayoutDescrFile",       
"pcbnew.page_layout_descr_file" );
 
  385    fromLegacyString( aCfg, 
"LastSpecctraDSNExportPath", 
"pcbnew.last_paths.specctra_dsn" );
 
  386    fromLegacyString( aCfg, 
"LastGenCADExportPath",      
"pcbnew.last_paths.gencad" );
 
  388    std::string bp = 
"board.design_settings.";
 
  392        wxString key = wxT( 
"DRCExclusion" );
 
  395        nlohmann::json exclusions = nlohmann::json::array();
 
  397        while( aCfg->Read( key, &str ) )
 
  399            exclusions.push_back( str );
 
  401            key = wxT( 
"DRCExclusion" );
 
  405        Set( bp + 
"drc_exclusions", exclusions );
 
  409    fromLegacy<bool>( aCfg,   
"AllowBlindVias",  bp + 
"rules.allow_blind_buried_vias" );
 
  415    if( !
fromLegacy<double>( aCfg, 
"MinThroughDrill", bp + 
"rules.min_through_hole_diameter" ) )
 
  418    fromLegacy<double>( aCfg, 
"MinMicroViaDiameter",  bp + 
"rules.min_microvia_diameter" );
 
  421    fromLegacy<double>( aCfg, 
"CopperEdgeClearance",  bp + 
"rules.min_copper_edge_clearance" );
 
  422    fromLegacy<double>( aCfg, 
"SolderMaskClearance",  bp + 
"rules.solder_mask_clearance" );
 
  424    fromLegacy<double>( aCfg, 
"SolderPasteClearance", bp + 
"rules.solder_paste_clearance" );
 
  425    fromLegacy<double>( aCfg, 
"SolderPasteRatio",     bp + 
"rules.solder_paste_margin_ratio" );
 
  428        fromLegacy<double>( aCfg, 
"ModuleOutlineThickness", bp + 
"defaults.silk_line_width" );
 
  436    if( !
fromLegacy<double>( aCfg, 
"SilkTextSizeThickness", bp + 
"defaults.silk_text_thickness" ) )
 
  437        fromLegacy<double>( aCfg, 
"ModuleTextSizeThickness", bp + 
"defaults.silk_text_thickness" );
 
  439    fromLegacy<bool>( aCfg, 
"SilkTextItalic",   bp + 
"defaults.silk_text_italic" );
 
  440    fromLegacy<bool>( aCfg, 
"SilkTextUpright",  bp + 
"defaults.silk_text_upright" );
 
  442    if( !
fromLegacy<double>( aCfg, 
"CopperLineWidth", bp + 
"defaults.copper_line_width" ) )
 
  445    if( !
fromLegacy<double>( aCfg, 
"CopperTextSizeV", bp + 
"defaults.copper_text_size_v" ) )
 
  448    if( !
fromLegacy<double>( aCfg, 
"CopperTextSizeH", bp + 
"defaults.copper_text_size_h" ) )
 
  451    if( !
fromLegacy<double>( aCfg, 
"CopperTextThickness", bp + 
"defaults.copper_text_thickness" ) )
 
  452        fromLegacy<double>( aCfg, 
"PcbTextThickness", bp + 
"defaults.copper_text_thickness" );
 
  454    fromLegacy<bool>( aCfg, 
"CopperTextItalic",   bp + 
"defaults.copper_text_italic" );
 
  455    fromLegacy<bool>( aCfg, 
"CopperTextUpright",  bp + 
"defaults.copper_text_upright" );
 
  457    if( !
fromLegacy<double>( aCfg, 
"EdgeCutLineWidth", bp + 
"defaults.board_outline_line_width" ) )
 
  459                            bp + 
"defaults.board_outline_line_width" );
 
  461    fromLegacy<double>( aCfg, 
"CourtyardLineWidth",   bp + 
"defaults.courtyard_line_width" );
 
  466    fromLegacy<double>( aCfg, 
"FabTextSizeThickness", bp + 
"defaults.fab_text_thickness" );
 
  468    fromLegacy<bool>(   aCfg, 
"FabTextUpright",       bp + 
"defaults.fab_text_upright" );
 
  470    if( !
fromLegacy<double>( aCfg, 
"OthersLineWidth", bp + 
"defaults.other_line_width" ) )
 
  471        fromLegacy<double>( aCfg, 
"ModuleOutlineThickness", bp + 
"defaults.other_line_width" );
 
  475    fromLegacy<double>( aCfg, 
"OthersTextSizeThickness", bp + 
"defaults.other_text_thickness" );
 
  476    fromLegacy<bool>(   aCfg, 
"OthersTextItalic",        bp + 
"defaults.other_text_italic" );
 
  477    fromLegacy<bool>(   aCfg, 
"OthersTextUpright",       bp + 
"defaults.other_text_upright" );
 
  479    fromLegacy<int>( aCfg, 
"DimensionUnits",     bp + 
"defaults.dimension_units" );
 
  480    fromLegacy<int>( aCfg, 
"DimensionPrecision", bp + 
"defaults.dimension_precision" );
 
  482    std::string sev = bp + 
"rule_severities";
 
  484    fromLegacy<bool>( aCfg, 
"RequireCourtyardDefinitions", sev + 
"legacy_no_courtyard_defined" );
 
  486    fromLegacy<bool>( aCfg, 
"ProhibitOverlappingCourtyards", sev + 
"legacy_courtyards_overlap" );
 
  490        wxString keyBase = 
"TrackWidth";
 
  491        wxString key     = keyBase;
 
  494        nlohmann::json widths = nlohmann::json::array();
 
  498        while( aCfg->Read( key, &val ) )
 
  500            widths.push_back( val );
 
  505        Set( bp + 
"track_widths", widths );
 
  510        wxString keyBase = 
"ViaDiameter";
 
  511        wxString key     = keyBase;
 
  515        nlohmann::json vias = nlohmann::json::array();
 
  519        while( aCfg->Read( key, &diameter ) )
 
  522            aCfg->Read( key << idx, &drill );
 
  524            nlohmann::json 
via = { { 
"diameter", diameter }, { 
"drill", drill } };
 
  525            vias.push_back( 
via );
 
  531        Set( bp + 
"via_dimensions", vias );
 
  536        wxString keyBase = 
"dPairWidth";
 
  537        wxString key     = keyBase;
 
  540        double   via_gap = 1.0;
 
  542        nlohmann::json pairs = nlohmann::json::array();
 
  546        while( aCfg->Read( key, &width ) )
 
  549            aCfg->Read( key << idx, &gap );
 
  552            aCfg->Read( key << idx, &via_gap );
 
  554            nlohmann::json pair = { { 
"width", width }, { 
"gap", gap }, { 
"via_gap", via_gap } };
 
  555            pairs.push_back( pair );
 
  561        Set( bp + 
"diff_pair_dimensions",  pairs );
 
  564    group_blacklist.insert( wxT( 
"/pcbnew" ) );
 
  567    group_blacklist.insert( wxT( 
"/general" ) );
 
  570    aCfg->SetPath( wxT( 
"/" ) );
 
  572    auto loadSheetNames =
 
  577                nlohmann::json arr   = nlohmann::json::array();
 
  581                aCfg->SetPath( wxT( 
"/sheetnames" ) );
 
  583                while( aCfg->Read( wxString::Format( 
"%d", sheet++ ), &entry ) )
 
  585                    wxArrayString tokens = wxSplit( entry, 
':' );
 
  587                    if( tokens.size() == 2 )
 
  589                        wxLogTrace( 
traceSettings, wxT( 
"%d: %s = %s" ), sheet, tokens[0],
 
  591                        arr.push_back( nlohmann::json::array( { tokens[0], tokens[1] } ) );
 
  595                Set( 
"sheets", arr );
 
  597                aCfg->SetPath( 
"/" );
 
  603    std::vector<wxString> groups;
 
  605    groups.emplace_back( wxEmptyString );
 
  607    auto loadLegacyPairs =
 
  608            [&]( 
const std::string& aGroup ) -> 
bool 
  610                wxLogTrace( 
traceSettings, wxT( 
"Migrating group %s" ), aGroup );
 
  617                while( aCfg->GetNextEntry( keyStr, index ) )
 
  619                    if( !aCfg->Read( keyStr, &val ) )
 
  622                    std::string key( keyStr.ToUTF8() );
 
  628                        Set( 
"legacy." + aGroup + 
"." + key, val );
 
  639    for( 
size_t i = 0; i < groups.size(); i++ )
 
  641        aCfg->SetPath( groups[i] );
 
  643        if( groups[i] == wxT( 
"/sheetnames" ) )
 
  645            ret |= loadSheetNames();
 
  649        aCfg->DeleteEntry( wxT( 
"last_client" ), 
true );
 
  650        aCfg->DeleteEntry( wxT( 
"update" ), 
true );
 
  651        aCfg->DeleteEntry( wxT( 
"version" ), 
true );
 
  653        ret &= loadLegacyPairs( groups[i].ToStdString() );
 
  657        while( aCfg->GetNextGroup( str, index ) )
 
  659            wxString 
group = groups[i] + 
"/" + str;
 
  661            if( !group_blacklist.count( 
group ) )
 
  662                groups.emplace_back( 
group );
 
  665        aCfg->SetPath( 
"/" );
 
 
  682            wxString projectName = 
m_project->GetProjectName();
 
  686            defaultSheet.
name = projectName;
 
  687            defaultSheet.
filename = projectName + 
".kicad_sch";
 
  694            wxLogTrace( 
traceSettings, wxT( 
"PROJECT_FILE: Migrated old single-root format to top_level_sheets" ) );
 
 
  722    wxString   oldProjectName = oldFilename.GetName();
 
  723    wxString   oldProjectPath = oldFilename.GetPath();
 
  729            [&]( wxString& aPath )
 
  731                if( aPath.StartsWith( oldProjectName + wxS( 
"." ) ) )
 
  732                    aPath.Replace( oldProjectName, aFile, 
false );
 
  733                else if( aPath.StartsWith( oldProjectPath + wxS( 
"/" ) ) )
 
  734                    aPath.Replace( oldProjectPath, aDirectory, 
false );
 
  742    auto updatePathByPtr =
 
  743            [&]( 
const std::string& aPtr )
 
  747                    updatePath( 
path.value() );
 
  752    updatePathByPtr( 
"schematic.page_layout_descr_file" );
 
  753    updatePathByPtr( 
"schematic.plot_directory" );
 
  754    updatePathByPtr( 
"schematic.ngspice.workbook_filename" );
 
  755    updatePathByPtr( 
"pcbnew.page_layout_descr_file" );
 
  758        updatePath( sheetInfo.filename );
 
 
  785    aJson = nlohmann::json::array( { aPair.first.AsString().ToUTF8(), aPair.second.ToUTF8() } );
 
 
  791    wxCHECK( aJson.is_array() && aJson.size() == 2,  );
 
  792    aPair.first  = 
KIID( wxString( aJson[0].get<std::string>().c_str(), wxConvUTF8 ) );
 
  793    aPair.second = wxString( aJson[1].get<std::string>().c_str(), wxConvUTF8 );
 
 
  799    aJson = nlohmann::json::object();
 
  801    aJson[
"name"] = aInfo.
name.ToUTF8();
 
  802    aJson[
"filename"] = aInfo.
filename.ToUTF8();
 
 
  808    wxCHECK( aJson.is_object(),  );
 
  810    if( aJson.contains( 
"uuid" ) )
 
  811        aInfo.
uuid = 
KIID( wxString( aJson[
"uuid"].get<std::string>().c_str(), wxConvUTF8 ) );
 
  813    if( aJson.contains( 
"name" ) )
 
  814        aInfo.
name = wxString( aJson[
"name"].get<std::string>().c_str(), wxConvUTF8 );
 
  816    if( aJson.contains( 
"filename" ) )
 
  817        aInfo.
filename = wxString( aJson[
"filename"].get<std::string>().c_str(), wxConvUTF8 );
 
 
bool fromLegacyString(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig string value to a given JSON pointer value.
 
bool fromLegacy(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig value to a given JSON pointer value.
 
void Set(const std::string &aPath, ValueType aVal)
Stores a value into the JSON document Will throw an exception if ValueType isn't something that the l...
 
virtual bool LoadFromFile(const wxString &aDirectory="")
Loads the backing file from disk and then calls Load()
 
void SetReadOnly(bool aReadOnly)
 
std::optional< ValueType > Get(const std::string &aPath) const
Fetches a value from within the JSON document.
 
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
 
void registerMigration(int aOldSchemaVersion, int aNewSchemaVersion, std::function< bool(void)> aMigrator)
Registers a migration from one schema version to another.
 
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
 
bool m_deleteLegacyAfterMigration
Whether or not to delete legacy file after migration.
 
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
 
void SetFilename(const wxString &aFilename)
 
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
Calls Store() and then writes the contents of the JSON document to a file.
 
wxString GetFilename() const
 
wxString AsString() const
 
Like a normal param, but with custom getter and setter functions.
 
static void MigrateToV9Layers(nlohmann::json &aJson)
 
static void MigrateToNamedRenderLayers(nlohmann::json &aJson)
 
Represents a list of strings holding directory paths.
 
Stores a path as a string with directory separators normalized to unix-style.
 
A helper for <wxString, wxString> maps.
 
std::map< wxString, wxString > m_TextVars
 
wxString getFileExt() const override
 
std::vector< LAYER_PAIR_INFO > m_LayerPairInfos
List of stored 3D viewports (view matrixes)
 
ERC_SETTINGS * m_ErcSettings
Eeschema params.
 
SCHEMATIC_SETTINGS * m_SchematicSettings
 
bool migrateSchema1To2()
IPC-2581 BOM settings.
 
wxString m_BoardDrawingSheetFile
PcbNew params.
 
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
 
struct IP2581_BOM m_IP2581Bom
Layer pair list for the board.
 
wxString m_PcbLastPath[LAST_PATH_SIZE]
MRU path storage.
 
PROJECT * m_project
A link to the owning PROJECT.
 
std::vector< TOP_LEVEL_SHEET_INFO > m_topLevelSheets
A list of top-level schematic sheets in this project.
 
std::vector< VIEWPORT > m_Viewports
List of stored layer presets.
 
BOARD_DESIGN_SETTINGS * m_BoardSettings
Board design settings for this project's board.
 
bool SaveAs(const wxString &aDirectory, const wxString &aFile)
 
std::map< wxString, std::vector< wxString > > m_BusAliases
Bus alias definitions for the schematic project.
 
std::vector< wxString > m_EquivalenceFiles
CvPcb params.
 
bool migrateSchema2To3()
Schema version 3: move layer presets to use named render layers.
 
wxString getLegacyFileExt() const override
 
std::vector< wxString > m_PinnedFootprintLibs
The list of pinned footprint libraries.
 
bool LoadFromFile(const wxString &aDirectory="") override
Loads the backing file from disk and then calls Load()
 
std::vector< FILE_INFO_PAIR > m_sheets
An list of schematic sheets in this project.
 
virtual bool MigrateFromLegacy(wxConfigBase *aCfg) override
Migrates from wxConfig to JSON-based configuration.
 
std::vector< LAYER_PRESET > m_LayerPresets
 
std::vector< FILE_INFO_PAIR > m_boards
A list of board files in this project.
 
std::shared_ptr< TUNING_PROFILES > m_tuningProfileParameters
Tuning profile parameters for this project.
 
wxArrayString m_LegacyLibNames
 
std::vector< wxString > m_PinnedSymbolLibs
Below are project-level settings that have not been moved to a dedicated file.
 
std::vector< VIEWPORT3D > m_Viewports3D
List of stored viewports (pos + zoom)
 
bool SaveToFile(const wxString &aDirectory="", bool aForce=false) override
Calls Store() and then writes the contents of the JSON document to a file.
 
PROJECT_FILE(const wxString &aFullPath)
Construct the project file for a project.
 
std::shared_ptr< COMPONENT_CLASS_SETTINGS > m_ComponentClassSettings
Component class settings for the project (owned here)
 
Container for project specific data.
 
static const std::string ProjectFileExtension
 
static const std::string LegacyProjectFileExtension
 
void to_json(nlohmann::json &aJson, const FILE_INFO_PAIR &aPair)
 
void from_json(const nlohmann::json &aJson, FILE_INFO_PAIR &aPair)
 
const int projectFileSchemaVersion
! Update the schema version whenever a migration is required
 
std::pair< KIID, wxString > FILE_INFO_PAIR
For files like sheets and boards, a pair of that object KIID and display name Display name is typical...
 
Information about a top-level schematic sheet.
 
KIID uuid
Unique identifier for the sheet.
 
wxString name
Display name for the sheet.
 
wxString filename
Relative path to the sheet file.
 
Definition of file extensions used in Kicad.