39 m_ErcSettings( nullptr ),
40 m_SchematicSettings( nullptr ),
99 [&]() -> nlohmann::json
101 nlohmann::json ret = nlohmann::json::array();
104 ret.push_back( libName );
108 [&](
const nlohmann::json& aJson )
110 if( aJson.empty() || !aJson.is_array() )
115 for(
const nlohmann::json& entry : aJson )
119 m_NetSettings = std::make_shared<NET_SETTINGS>(
this,
"net_settings" );
154 auto p(
"/board/layer_presets"_json_pointer );
161 for( nlohmann::json& entry : presets )
174 std::set<wxString> group_blacklist;
181 auto loadPinnedLibs =
182 [&](
const std::string& aDest )
185 wxString libKey = wxT(
"PinnedItems" );
188 nlohmann::json libs = nlohmann::json::array();
190 while( aCfg->Read( libKey, &str ) )
192 libs.push_back( str );
194 aCfg->DeleteEntry( libKey,
true );
196 libKey = wxT(
"PinnedItems" );
197 libKey << ++libIndex;
203 aCfg->SetPath( wxT(
"/LibeditFrame" ) );
204 loadPinnedLibs(
"libraries.pinned_symbol_libs" );
206 aCfg->SetPath( wxT(
"/ModEditFrame" ) );
207 loadPinnedLibs(
"libraries.pinned_footprint_libs" );
209 aCfg->SetPath( wxT(
"/cvpcb/equfiles" ) );
213 wxString eqKey = wxT(
"EquName" );
216 nlohmann::json eqs = nlohmann::json::array();
218 while( aCfg->Read( eqKey, &str ) )
220 eqs.push_back( str );
222 eqKey = wxT(
"EquName" );
226 Set(
"cvpcb.equivalence_files", eqs );
230 group_blacklist.insert( wxT(
"/cvpcb" ) );
232 aCfg->SetPath( wxT(
"/eeschema" ) );
235 aCfg->SetPath( wxT(
"/eeschema/libraries" ) );
239 wxString libKey = wxT(
"LibName" );
242 nlohmann::json libs = nlohmann::json::array();
244 while( aCfg->Read( libKey, &str ) )
246 libs.push_back( str );
248 libKey = wxT(
"LibName" );
252 Set(
"schematic.legacy_lib_list", libs );
255 group_blacklist.insert( wxT(
"/eeschema" ) );
257 aCfg->SetPath( wxT(
"/text_variables" ) );
264 nlohmann::json vars = nlohmann::json();
266 while( aCfg->Read( txtKey, &str ) )
268 wxArrayString tokens = wxSplit( str,
':' );
270 if( tokens.size() == 2 )
271 vars[ tokens[0].ToStdString() ] = tokens[1];
277 Set(
"text_variables", vars );
280 group_blacklist.insert( wxT(
"/text_variables" ) );
282 aCfg->SetPath( wxT(
"/schematic_editor" ) );
284 fromLegacyString( aCfg,
"PageLayoutDescrFile",
"schematic.page_layout_descr_file" );
287 fromLegacy<bool>( aCfg,
"SpiceAjustPassiveValues",
"schematic.spice_adjust_passive_values" );
288 fromLegacy<int>( aCfg,
"SubpartIdSeparator",
"schematic.subpart_id_separator" );
289 fromLegacy<int>( aCfg,
"SubpartFirstId",
"schematic.subpart_first_id" );
291 fromLegacy<int>( aCfg,
"LineThickness",
"schematic.drawing.default_line_thickness" );
292 fromLegacy<int>( aCfg,
"WireThickness",
"schematic.drawing.default_wire_thickness" );
293 fromLegacy<int>( aCfg,
"BusThickness",
"schematic.drawing.default_bus_thickness" );
294 fromLegacy<int>( aCfg,
"LabSize",
"schematic.drawing.default_text_size" );
296 if( !fromLegacy<int>( aCfg,
"PinSymbolSize",
"schematic.drawing.pin_symbol_size" ) )
299 Set(
"schematic.drawing.pin_symbol_size", 0 );
302 fromLegacy<int>( aCfg,
"JunctionSize",
"schematic.drawing.default_junction_size" );
304 fromLegacyString( aCfg,
"FieldNameTemplates",
"schematic.drawing.field_names" );
306 if( !fromLegacy<double>( aCfg,
"TextOffsetRatio",
"schematic.drawing.text_offset_ratio" ) )
309 Set(
"schematic.drawing.text_offset_ratio", 0.08 );
310 Set(
"schematic.drawing.label_size_ratio", 0.25 );
314 group_blacklist.insert( wxT(
"/schematic_editor" ) );
316 aCfg->SetPath( wxT(
"/pcbnew" ) );
318 fromLegacyString( aCfg,
"PageLayoutDescrFile",
"pcbnew.page_layout_descr_file" );
323 fromLegacyString( aCfg,
"LastSpecctraDSNExportPath",
"pcbnew.last_paths.specctra_dsn" );
324 fromLegacyString( aCfg,
"LastGenCADExportPath",
"pcbnew.last_paths.gencad" );
326 std::string bp =
"board.design_settings.";
330 wxString key = wxT(
"DRCExclusion" );
333 nlohmann::json exclusions = nlohmann::json::array();
335 while( aCfg->Read( key, &str ) )
337 exclusions.push_back( str );
339 key = wxT(
"DRCExclusion" );
343 Set( bp +
"drc_exclusions", exclusions );
346 fromLegacy<bool>( aCfg,
"AllowMicroVias", bp +
"rules.allow_microvias" );
347 fromLegacy<bool>( aCfg,
"AllowBlindVias", bp +
"rules.allow_blind_buried_vias" );
348 fromLegacy<double>( aCfg,
"MinClearance", bp +
"rules.min_clearance" );
349 fromLegacy<double>( aCfg,
"MinTrackWidth", bp +
"rules.min_track_width" );
350 fromLegacy<double>( aCfg,
"MinViaAnnulus", bp +
"rules.min_via_annulus" );
351 fromLegacy<double>( aCfg,
"MinViaDiameter", bp +
"rules.min_via_diameter" );
353 if( !fromLegacy<double>( aCfg,
"MinThroughDrill", bp +
"rules.min_through_hole_diameter" ) )
354 fromLegacy<double>( aCfg,
"MinViaDrill", bp +
"rules.min_through_hole_diameter" );
356 fromLegacy<double>( aCfg,
"MinMicroViaDiameter", bp +
"rules.min_microvia_diameter" );
357 fromLegacy<double>( aCfg,
"MinMicroViaDrill", bp +
"rules.min_microvia_drill" );
358 fromLegacy<double>( aCfg,
"MinHoleToHole", bp +
"rules.min_hole_to_hole" );
359 fromLegacy<double>( aCfg,
"CopperEdgeClearance", bp +
"rules.min_copper_edge_clearance" );
360 fromLegacy<double>( aCfg,
"SolderMaskClearance", bp +
"rules.solder_mask_clearance" );
361 fromLegacy<double>( aCfg,
"SolderMaskMinWidth", bp +
"rules.solder_mask_min_width" );
362 fromLegacy<double>( aCfg,
"SolderPasteClearance", bp +
"rules.solder_paste_clearance" );
363 fromLegacy<double>( aCfg,
"SolderPasteRatio", bp +
"rules.solder_paste_margin_ratio" );
365 if( !fromLegacy<double>( aCfg,
"SilkLineWidth", bp +
"defaults.silk_line_width" ) )
366 fromLegacy<double>( aCfg,
"ModuleOutlineThickness", bp +
"defaults.silk_line_width" );
368 if( !fromLegacy<double>( aCfg,
"SilkTextSizeV", bp +
"defaults.silk_text_size_v" ) )
369 fromLegacy<double>( aCfg,
"ModuleTextSizeV", bp +
"defaults.silk_text_size_v" );
371 if( !fromLegacy<double>( aCfg,
"SilkTextSizeH", bp +
"defaults.silk_text_size_h" ) )
372 fromLegacy<double>( aCfg,
"ModuleTextSizeH", bp +
"defaults.silk_text_size_h" );
374 if( !fromLegacy<double>( aCfg,
"SilkTextSizeThickness", bp +
"defaults.silk_text_thickness" ) )
375 fromLegacy<double>( aCfg,
"ModuleTextSizeThickness", bp +
"defaults.silk_text_thickness" );
377 fromLegacy<bool>( aCfg,
"SilkTextItalic", bp +
"defaults.silk_text_italic" );
378 fromLegacy<bool>( aCfg,
"SilkTextUpright", bp +
"defaults.silk_text_upright" );
380 if( !fromLegacy<double>( aCfg,
"CopperLineWidth", bp +
"defaults.copper_line_width" ) )
381 fromLegacy<double>( aCfg,
"DrawSegmentWidth", bp +
"defaults.copper_line_width" );
383 if( !fromLegacy<double>( aCfg,
"CopperTextSizeV", bp +
"defaults.copper_text_size_v" ) )
384 fromLegacy<double>( aCfg,
"PcbTextSizeV", bp +
"defaults.copper_text_size_v" );
386 if( !fromLegacy<double>( aCfg,
"CopperTextSizeH", bp +
"defaults.copper_text_size_h" ) )
387 fromLegacy<double>( aCfg,
"PcbTextSizeH", bp +
"defaults.copper_text_size_h" );
389 if( !fromLegacy<double>( aCfg,
"CopperTextThickness", bp +
"defaults.copper_text_thickness" ) )
390 fromLegacy<double>( aCfg,
"PcbTextThickness", bp +
"defaults.copper_text_thickness" );
392 fromLegacy<bool>( aCfg,
"CopperTextItalic", bp +
"defaults.copper_text_italic" );
393 fromLegacy<bool>( aCfg,
"CopperTextUpright", bp +
"defaults.copper_text_upright" );
395 if( !fromLegacy<double>( aCfg,
"EdgeCutLineWidth", bp +
"defaults.board_outline_line_width" ) )
396 fromLegacy<double>( aCfg,
"BoardOutlineThickness", bp +
"defaults.board_outline_line_width" );
398 fromLegacy<double>( aCfg,
"CourtyardLineWidth", bp +
"defaults.courtyard_line_width" );
400 fromLegacy<double>( aCfg,
"FabLineWidth", bp +
"defaults.fab_line_width" );
401 fromLegacy<double>( aCfg,
"FabTextSizeV", bp +
"defaults.fab_text_size_v" );
402 fromLegacy<double>( aCfg,
"FabTextSizeH", bp +
"defaults.fab_text_size_h" );
403 fromLegacy<double>( aCfg,
"FabTextSizeThickness", bp +
"defaults.fab_text_thickness" );
404 fromLegacy<bool>( aCfg,
"FabTextItalic", bp +
"defaults.fab_text_italic" );
405 fromLegacy<bool>( aCfg,
"FabTextUpright", bp +
"defaults.fab_text_upright" );
407 if( !fromLegacy<double>( aCfg,
"OthersLineWidth", bp +
"defaults.other_line_width" ) )
408 fromLegacy<double>( aCfg,
"ModuleOutlineThickness", bp +
"defaults.other_line_width" );
410 fromLegacy<double>( aCfg,
"OthersTextSizeV", bp +
"defaults.other_text_size_v" );
411 fromLegacy<double>( aCfg,
"OthersTextSizeH", bp +
"defaults.other_text_size_h" );
412 fromLegacy<double>( aCfg,
"OthersTextSizeThickness", bp +
"defaults.other_text_thickness" );
413 fromLegacy<bool>( aCfg,
"OthersTextItalic", bp +
"defaults.other_text_italic" );
414 fromLegacy<bool>( aCfg,
"OthersTextUpright", bp +
"defaults.other_text_upright" );
416 fromLegacy<int>( aCfg,
"DimensionUnits", bp +
"defaults.dimension_units" );
417 fromLegacy<int>( aCfg,
"DimensionPrecision", bp +
"defaults.dimension_precision" );
419 std::string sev = bp +
"rule_severities";
421 fromLegacy<bool>( aCfg,
"RequireCourtyardDefinitions", sev +
"legacy_no_courtyard_defined" );
423 fromLegacy<bool>( aCfg,
"ProhibitOverlappingCourtyards", sev +
"legacy_courtyards_overlap" );
427 wxString keyBase =
"TrackWidth";
428 wxString key = keyBase;
431 nlohmann::json widths = nlohmann::json::array();
435 while( aCfg->Read( key, &val ) )
437 widths.push_back( val );
442 Set( bp +
"track_widths", widths );
447 wxString keyBase =
"ViaDiameter";
448 wxString key = keyBase;
452 nlohmann::json vias = nlohmann::json::array();
456 while( aCfg->Read( key, &diameter ) )
459 aCfg->Read( key << idx, &drill );
461 nlohmann::json
via = { {
"diameter", diameter }, {
"drill", drill } };
462 vias.push_back(
via );
468 Set( bp +
"via_dimensions", vias );
473 wxString keyBase =
"dPairWidth";
474 wxString key = keyBase;
477 double via_gap = 1.0;
479 nlohmann::json pairs = nlohmann::json::array();
483 while( aCfg->Read( key, &width ) )
486 aCfg->Read( key << idx, &gap );
489 aCfg->Read( key << idx, &via_gap );
491 nlohmann::json pair = { {
"width", width }, {
"gap", gap }, {
"via_gap", via_gap } };
492 pairs.push_back( pair );
498 Set( bp +
"diff_pair_dimensions", pairs );
501 group_blacklist.insert( wxT(
"/pcbnew" ) );
504 group_blacklist.insert( wxT(
"/general" ) );
507 aCfg->SetPath( wxT(
"/" ) );
509 auto loadSheetNames =
514 nlohmann::json arr = nlohmann::json::array();
518 aCfg->SetPath( wxT(
"/sheetnames" ) );
520 while( aCfg->Read( wxString::Format(
"%d", sheet++ ), &entry ) )
522 wxArrayString tokens = wxSplit( entry,
':' );
524 if( tokens.size() == 2 )
526 wxLogTrace(
traceSettings, wxT(
"%d: %s = %s" ), sheet, tokens[0],
528 arr.push_back( nlohmann::json::array( { tokens[0], tokens[1] } ) );
532 Set(
"sheets", arr );
534 aCfg->SetPath(
"/" );
540 std::vector<wxString> groups;
542 groups.emplace_back( wxEmptyString );
544 auto loadLegacyPairs =
545 [&](
const std::string& aGroup ) ->
bool
547 wxLogTrace(
traceSettings, wxT(
"Migrating group %s" ), aGroup );
554 while( aCfg->GetNextEntry( keyStr, index ) )
556 if( !aCfg->Read( keyStr, &val ) )
559 std::string key( keyStr.ToUTF8() );
565 Set(
"legacy." + aGroup +
"." + key, val );
576 for(
size_t i = 0; i < groups.size(); i++ )
578 aCfg->SetPath( groups[i] );
580 if( groups[i] == wxT(
"/sheetnames" ) )
582 ret |= loadSheetNames();
586 aCfg->DeleteEntry( wxT(
"last_client" ),
true );
587 aCfg->DeleteEntry( wxT(
"update" ),
true );
588 aCfg->DeleteEntry( wxT(
"version" ),
true );
590 ret &= loadLegacyPairs( groups[i].ToStdString() );
594 while( aCfg->GetNextGroup( str, index ) )
596 wxString
group = groups[i] +
"/" + str;
598 if( !group_blacklist.count(
group ) )
599 groups.emplace_back(
group );
602 aCfg->SetPath(
"/" );
622 wxString oldProjectName = oldFilename.GetName();
623 wxString oldProjectPath = oldFilename.GetPath();
629 [&]( wxString& aPath )
631 if( aPath.StartsWith( oldProjectName + wxS(
"." ) ) )
632 aPath.Replace( oldProjectName, aFile,
false );
633 else if( aPath.StartsWith( oldProjectPath + wxS(
"/" ) ) )
634 aPath.Replace( oldProjectPath, aDirectory,
false );
642 auto updatePathByPtr =
643 [&](
const std::string& aPtr )
645 if( std::optional<wxString>
path = Get<wxString>( aPtr ) )
647 updatePath(
path.value() );
652 updatePathByPtr(
"schematic.page_layout_descr_file" );
653 updatePathByPtr(
"schematic.plot_directory" );
654 updatePathByPtr(
"schematic.ngspice.workbook_filename" );
655 updatePathByPtr(
"pcbnew.page_layout_descr_file" );
678 aJson = nlohmann::json::array( { aPair.first.AsString().ToUTF8(), aPair.second.ToUTF8() } );
684 wxCHECK( aJson.is_array() && aJson.size() == 2, );
685 aPair.first =
KIID( wxString( aJson[0].get<std::string>().c_str(), wxConvUTF8 ) );
686 aPair.second = wxString( aJson[1].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.
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...
void SetReadOnly(bool aReadOnly)
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.
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
Like a normal param, but with custom getter and setter functions.
static void MigrateToV9Layers(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)
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< VIEWPORT > m_Viewports
List of stored layer presets.
bool SaveAs(const wxString &aDirectory, const wxString &aFile)
std::vector< wxString > m_EquivalenceFiles
CvPcb params.
wxString getLegacyFileExt() const override
std::vector< wxString > m_PinnedFootprintLibs
The list of pinned footprint libraries.
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.
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.
Container for project specific data.
virtual const wxString GetProjectName() const
Return the short name of the project.
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...
wxString mfg
Manufacturer name column.
wxString MPN
Manufacturer part number column.
wxString id
Internal ID column.
wxString dist
Distributor name column.
wxString distPN
Distributor part number column.
Definition of file extensions used in Kicad.