KiCad PCB EDA Suite
Loading...
Searching...
No Matches
project_file.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020 CERN
5 * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Jon Evans <[email protected]>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <config_params.h>
23#include <project.h>
28#include <settings/parameters.h>
30#include <wx/config.h>
31#include <wx/log.h>
32
33
36
37
38PROJECT_FILE::PROJECT_FILE( const wxString& aFullPath ) :
40 m_ErcSettings( nullptr ),
41 m_SchematicSettings( nullptr ),
42 m_BoardSettings(),
43 m_sheets(),
44 m_boards(),
45 m_project( nullptr )
46{
47 // Keep old files around
49
50 m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "sheets", &m_sheets, {} ) );
51
52 m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "boards", &m_boards, {} ) );
53
54 m_params.emplace_back( new PARAM_WXSTRING_MAP( "text_variables", &m_TextVars, {} ) );
55
56 m_params.emplace_back(
57 new PARAM_LIST<wxString>( "libraries.pinned_symbol_libs", &m_PinnedSymbolLibs, {} ) );
58
59 m_params.emplace_back( new PARAM_LIST<wxString>(
60 "libraries.pinned_footprint_libs", &m_PinnedFootprintLibs, {} ) );
61
62 m_params.emplace_back(
63 new PARAM_PATH_LIST( "cvpcb.equivalence_files", &m_EquivalenceFiles, {} ) );
64
65 m_params.emplace_back(
66 new PARAM_PATH( "pcbnew.page_layout_descr_file", &m_BoardDrawingSheetFile, "" ) );
67
68 m_params.emplace_back(
69 new PARAM_PATH( "pcbnew.last_paths.netlist", &m_PcbLastPath[LAST_PATH_NETLIST], "" ) );
70
71 m_params.emplace_back(
72 new PARAM_PATH( "pcbnew.last_paths.step", &m_PcbLastPath[LAST_PATH_STEP], "" ) );
73
74 m_params.emplace_back(
75 new PARAM_PATH( "pcbnew.last_paths.idf", &m_PcbLastPath[LAST_PATH_IDF], "" ) );
76
77 m_params.emplace_back(
78 new PARAM_PATH( "pcbnew.last_paths.vrml", &m_PcbLastPath[LAST_PATH_VRML], "" ) );
79
80 m_params.emplace_back( new PARAM_PATH(
81 "pcbnew.last_paths.specctra_dsn", &m_PcbLastPath[LAST_PATH_SPECCTRADSN], "" ) );
82
83 m_params.emplace_back(
84 new PARAM_PATH( "pcbnew.last_paths.gencad", &m_PcbLastPath[LAST_PATH_GENCAD], "" ) );
85
86 m_params.emplace_back( new PARAM<wxString>( "schematic.legacy_lib_dir", &m_LegacyLibDir, "" ) );
87
88 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "schematic.legacy_lib_list",
89 [&]() -> nlohmann::json
90 {
91 nlohmann::json ret = nlohmann::json::array();
92
93 for( const wxString& libName : m_LegacyLibNames )
94 ret.push_back( libName );
95
96 return ret;
97 },
98 [&]( const nlohmann::json& aJson )
99 {
100 if( aJson.empty() || !aJson.is_array() )
101 return;
102
103 m_LegacyLibNames.clear();
104
105 for( const nlohmann::json& entry : aJson )
106 m_LegacyLibNames.push_back( entry.get<wxString>() );
107 }, {} ) );
108
109 m_NetSettings = std::make_shared<NET_SETTINGS>( this, "net_settings" );
110
111 m_params.emplace_back( new PARAM_LAYER_PRESET( "board.layer_presets", &m_LayerPresets ) );
112
113 m_params.emplace_back( new PARAM_VIEWPORT( "board.viewports", &m_Viewports ) );
114
115 m_params.emplace_back( new PARAM_VIEWPORT3D( "board.3dviewports", &m_Viewports3D ) );
116}
117
118
119bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
120{
121 bool ret = true;
122 wxString str;
123 long index = 0;
124
125 std::set<wxString> group_blacklist;
126
127 // Legacy files don't store board info; they assume board matches project name
128 // We will leave m_boards empty here so it can be populated with other code
129
130 // First handle migration of data that will be stored locally in this object
131
132 auto loadPinnedLibs =
133 [&]( const std::string& aDest )
134 {
135 int libIndex = 1;
136 wxString libKey = wxT( "PinnedItems" );
137 libKey << libIndex;
138
139 nlohmann::json libs = nlohmann::json::array();
140
141 while( aCfg->Read( libKey, &str ) )
142 {
143 libs.push_back( str );
144
145 aCfg->DeleteEntry( libKey, true );
146
147 libKey = wxT( "PinnedItems" );
148 libKey << ++libIndex;
149 }
150
151 Set( aDest, libs );
152 };
153
154 aCfg->SetPath( wxT( "/LibeditFrame" ) );
155 loadPinnedLibs( "libraries.pinned_symbol_libs" );
156
157 aCfg->SetPath( wxT( "/ModEditFrame" ) );
158 loadPinnedLibs( "libraries.pinned_footprint_libs" );
159
160 aCfg->SetPath( wxT( "/cvpcb/equfiles" ) );
161
162 {
163 int eqIdx = 1;
164 wxString eqKey = wxT( "EquName" );
165 eqKey << eqIdx;
166
167 nlohmann::json eqs = nlohmann::json::array();
168
169 while( aCfg->Read( eqKey, &str ) )
170 {
171 eqs.push_back( str );
172
173 eqKey = wxT( "EquName" );
174 eqKey << ++eqIdx;
175 }
176
177 Set( "cvpcb.equivalence_files", eqs );
178 }
179
180 // All CvPcb params that we want to keep have been migrated above
181 group_blacklist.insert( wxT( "/cvpcb" ) );
182
183 aCfg->SetPath( wxT( "/eeschema" ) );
184 fromLegacyString( aCfg, "LibDir", "schematic.legacy_lib_dir" );
185
186 aCfg->SetPath( wxT( "/eeschema/libraries" ) );
187
188 {
189 int libIdx = 1;
190 wxString libKey = wxT( "LibName" );
191 libKey << libIdx;
192
193 nlohmann::json libs = nlohmann::json::array();
194
195 while( aCfg->Read( libKey, &str ) )
196 {
197 libs.push_back( str );
198
199 libKey = wxT( "LibName" );
200 libKey << ++libIdx;
201 }
202
203 Set( "schematic.legacy_lib_list", libs );
204 }
205
206 group_blacklist.insert( wxT( "/eeschema" ) );
207
208 aCfg->SetPath( wxT( "/text_variables" ) );
209
210 {
211 int txtIdx = 1;
212 wxString txtKey;
213 txtKey << txtIdx;
214
215 nlohmann::json vars = nlohmann::json();
216
217 while( aCfg->Read( txtKey, &str ) )
218 {
219 wxArrayString tokens = wxSplit( str, ':' );
220
221 if( tokens.size() == 2 )
222 vars[ tokens[0].ToStdString() ] = tokens[1];
223
224 txtKey.clear();
225 txtKey << ++txtIdx;
226 }
227
228 Set( "text_variables", vars );
229 }
230
231 group_blacklist.insert( wxT( "/text_variables" ) );
232
233 aCfg->SetPath( wxT( "/schematic_editor" ) );
234
235 fromLegacyString( aCfg, "PageLayoutDescrFile", "schematic.page_layout_descr_file" );
236 fromLegacyString( aCfg, "PlotDirectoryName", "schematic.plot_directory" );
237 fromLegacyString( aCfg, "NetFmtName", "schematic.net_format_name" );
238 fromLegacy<bool>( aCfg, "SpiceAjustPassiveValues", "schematic.spice_adjust_passive_values" );
239 fromLegacy<int>( aCfg, "SubpartIdSeparator", "schematic.subpart_id_separator" );
240 fromLegacy<int>( aCfg, "SubpartFirstId", "schematic.subpart_first_id" );
241
242 fromLegacy<int>( aCfg, "LineThickness", "schematic.drawing.default_line_thickness" );
243 fromLegacy<int>( aCfg, "WireThickness", "schematic.drawing.default_wire_thickness" );
244 fromLegacy<int>( aCfg, "BusThickness", "schematic.drawing.default_bus_thickness" );
245 fromLegacy<int>( aCfg, "LabSize", "schematic.drawing.default_text_size" );
246
247 if( !fromLegacy<int>( aCfg, "PinSymbolSize", "schematic.drawing.pin_symbol_size" ) )
248 {
249 // Use the default symbol size algorithm of Eeschema V5 (based on pin name/number size)
250 Set( "schematic.drawing.pin_symbol_size", 0 );
251 }
252
253 fromLegacy<int>( aCfg, "JunctionSize", "schematic.drawing.default_junction_size" );
254
255 fromLegacyString( aCfg, "FieldNameTemplates", "schematic.drawing.field_names" );
256
257 if( !fromLegacy<double>( aCfg, "TextOffsetRatio", "schematic.drawing.text_offset_ratio" ) )
258 {
259 // Use the spacing of Eeschema V5
260 Set( "schematic.drawing.text_offset_ratio", 0.08 );
261 Set( "schematic.drawing.label_size_ratio", 0.25 );
262 }
263
264 // All schematic_editor keys we keep are migrated above
265 group_blacklist.insert( wxT( "/schematic_editor" ) );
266
267 aCfg->SetPath( wxT( "/pcbnew" ) );
268
269 fromLegacyString( aCfg, "PageLayoutDescrFile", "pcbnew.page_layout_descr_file" );
270 fromLegacyString( aCfg, "LastNetListRead", "pcbnew.last_paths.netlist" );
271 fromLegacyString( aCfg, "LastSTEPExportPath", "pcbnew.last_paths.step" );
272 fromLegacyString( aCfg, "LastIDFExportPath", "pcbnew.last_paths.idf" );
273 fromLegacyString( aCfg, "LastVRMLExportPath", "pcbnew.last_paths.vmrl" );
274 fromLegacyString( aCfg, "LastSpecctraDSNExportPath", "pcbnew.last_paths.specctra_dsn" );
275 fromLegacyString( aCfg, "LastGenCADExportPath", "pcbnew.last_paths.gencad" );
276
277 std::string bp = "board.design_settings.";
278
279 {
280 int idx = 1;
281 wxString key = wxT( "DRCExclusion" );
282 key << idx;
283
284 nlohmann::json exclusions = nlohmann::json::array();
285
286 while( aCfg->Read( key, &str ) )
287 {
288 exclusions.push_back( str );
289
290 key = wxT( "DRCExclusion" );
291 key << ++idx;
292 }
293
294 Set( bp + "drc_exclusions", exclusions );
295 }
296
297 fromLegacy<bool>( aCfg, "AllowMicroVias", bp + "rules.allow_microvias" );
298 fromLegacy<bool>( aCfg, "AllowBlindVias", bp + "rules.allow_blind_buried_vias" );
299 fromLegacy<double>( aCfg, "MinClearance", bp + "rules.min_clearance" );
300 fromLegacy<double>( aCfg, "MinTrackWidth", bp + "rules.min_track_width" );
301 fromLegacy<double>( aCfg, "MinViaAnnulus", bp + "rules.min_via_annulus" );
302 fromLegacy<double>( aCfg, "MinViaDiameter", bp + "rules.min_via_diameter" );
303
304 if( !fromLegacy<double>( aCfg, "MinThroughDrill", bp + "rules.min_through_hole_diameter" ) )
305 fromLegacy<double>( aCfg, "MinViaDrill", bp + "rules.min_through_hole_diameter" );
306
307 fromLegacy<double>( aCfg, "MinMicroViaDiameter", bp + "rules.min_microvia_diameter" );
308 fromLegacy<double>( aCfg, "MinMicroViaDrill", bp + "rules.min_microvia_drill" );
309 fromLegacy<double>( aCfg, "MinHoleToHole", bp + "rules.min_hole_to_hole" );
310 fromLegacy<double>( aCfg, "CopperEdgeClearance", bp + "rules.min_copper_edge_clearance" );
311 fromLegacy<double>( aCfg, "SolderMaskClearance", bp + "rules.solder_mask_clearance" );
312 fromLegacy<double>( aCfg, "SolderMaskMinWidth", bp + "rules.solder_mask_min_width" );
313 fromLegacy<double>( aCfg, "SolderPasteClearance", bp + "rules.solder_paste_clearance" );
314 fromLegacy<double>( aCfg, "SolderPasteRatio", bp + "rules.solder_paste_margin_ratio" );
315
316 if( !fromLegacy<double>( aCfg, "SilkLineWidth", bp + "defaults.silk_line_width" ) )
317 fromLegacy<double>( aCfg, "ModuleOutlineThickness", bp + "defaults.silk_line_width" );
318
319 if( !fromLegacy<double>( aCfg, "SilkTextSizeV", bp + "defaults.silk_text_size_v" ) )
320 fromLegacy<double>( aCfg, "ModuleTextSizeV", bp + "defaults.silk_text_size_v" );
321
322 if( !fromLegacy<double>( aCfg, "SilkTextSizeH", bp + "defaults.silk_text_size_h" ) )
323 fromLegacy<double>( aCfg, "ModuleTextSizeH", bp + "defaults.silk_text_size_h" );
324
325 if( !fromLegacy<double>( aCfg, "SilkTextSizeThickness", bp + "defaults.silk_text_thickness" ) )
326 fromLegacy<double>( aCfg, "ModuleTextSizeThickness", bp + "defaults.silk_text_thickness" );
327
328 fromLegacy<bool>( aCfg, "SilkTextItalic", bp + "defaults.silk_text_italic" );
329 fromLegacy<bool>( aCfg, "SilkTextUpright", bp + "defaults.silk_text_upright" );
330
331 if( !fromLegacy<double>( aCfg, "CopperLineWidth", bp + "defaults.copper_line_width" ) )
332 fromLegacy<double>( aCfg, "DrawSegmentWidth", bp + "defaults.copper_line_width" );
333
334 if( !fromLegacy<double>( aCfg, "CopperTextSizeV", bp + "defaults.copper_text_size_v" ) )
335 fromLegacy<double>( aCfg, "PcbTextSizeV", bp + "defaults.copper_text_size_v" );
336
337 if( !fromLegacy<double>( aCfg, "CopperTextSizeH", bp + "defaults.copper_text_size_h" ) )
338 fromLegacy<double>( aCfg, "PcbTextSizeH", bp + "defaults.copper_text_size_h" );
339
340 if( !fromLegacy<double>( aCfg, "CopperTextThickness", bp + "defaults.copper_text_thickness" ) )
341 fromLegacy<double>( aCfg, "PcbTextThickness", bp + "defaults.copper_text_thickness" );
342
343 fromLegacy<bool>( aCfg, "CopperTextItalic", bp + "defaults.copper_text_italic" );
344 fromLegacy<bool>( aCfg, "CopperTextUpright", bp + "defaults.copper_text_upright" );
345
346 if( !fromLegacy<double>( aCfg, "EdgeCutLineWidth", bp + "defaults.board_outline_line_width" ) )
347 fromLegacy<double>( aCfg, "BoardOutlineThickness", bp + "defaults.board_outline_line_width" );
348
349 fromLegacy<double>( aCfg, "CourtyardLineWidth", bp + "defaults.courtyard_line_width" );
350
351 fromLegacy<double>( aCfg, "FabLineWidth", bp + "defaults.fab_line_width" );
352 fromLegacy<double>( aCfg, "FabTextSizeV", bp + "defaults.fab_text_size_v" );
353 fromLegacy<double>( aCfg, "FabTextSizeH", bp + "defaults.fab_text_size_h" );
354 fromLegacy<double>( aCfg, "FabTextSizeThickness", bp + "defaults.fab_text_thickness" );
355 fromLegacy<bool>( aCfg, "FabTextItalic", bp + "defaults.fab_text_italic" );
356 fromLegacy<bool>( aCfg, "FabTextUpright", bp + "defaults.fab_text_upright" );
357
358 if( !fromLegacy<double>( aCfg, "OthersLineWidth", bp + "defaults.other_line_width" ) )
359 fromLegacy<double>( aCfg, "ModuleOutlineThickness", bp + "defaults.other_line_width" );
360
361 fromLegacy<double>( aCfg, "OthersTextSizeV", bp + "defaults.other_text_size_v" );
362 fromLegacy<double>( aCfg, "OthersTextSizeH", bp + "defaults.other_text_size_h" );
363 fromLegacy<double>( aCfg, "OthersTextSizeThickness", bp + "defaults.other_text_thickness" );
364 fromLegacy<bool>( aCfg, "OthersTextItalic", bp + "defaults.other_text_italic" );
365 fromLegacy<bool>( aCfg, "OthersTextUpright", bp + "defaults.other_text_upright" );
366
367 fromLegacy<int>( aCfg, "DimensionUnits", bp + "defaults.dimension_units" );
368 fromLegacy<int>( aCfg, "DimensionPrecision", bp + "defaults.dimension_precision" );
369
370 std::string sev = bp + "rule_severities";
371
372 fromLegacy<bool>( aCfg, "RequireCourtyardDefinitions", sev + "legacy_no_courtyard_defined" );
373
374 fromLegacy<bool>( aCfg, "ProhibitOverlappingCourtyards", sev + "legacy_courtyards_overlap" );
375
376 {
377 int idx = 1;
378 wxString keyBase = "TrackWidth";
379 wxString key = keyBase;
380 double val;
381
382 nlohmann::json widths = nlohmann::json::array();
383
384 key << idx;
385
386 while( aCfg->Read( key, &val ) )
387 {
388 widths.push_back( val );
389 key = keyBase;
390 key << ++idx;
391 }
392
393 Set( bp + "track_widths", widths );
394 }
395
396 {
397 int idx = 1;
398 wxString keyBase = "ViaDiameter";
399 wxString key = keyBase;
400 double diameter;
401 double drill = 1.0;
402
403 nlohmann::json vias = nlohmann::json::array();
404
405 key << idx;
406
407 while( aCfg->Read( key, &diameter ) )
408 {
409 key = "ViaDrill";
410 aCfg->Read( key << idx, &drill );
411
412 nlohmann::json via = { { "diameter", diameter }, { "drill", drill } };
413 vias.push_back( via );
414
415 key = keyBase;
416 key << ++idx;
417 }
418
419 Set( bp + "via_dimensions", vias );
420 }
421
422 {
423 int idx = 1;
424 wxString keyBase = "dPairWidth";
425 wxString key = keyBase;
426 double width;
427 double gap = 1.0;
428 double via_gap = 1.0;
429
430 nlohmann::json pairs = nlohmann::json::array();
431
432 key << idx;
433
434 while( aCfg->Read( key, &width ) )
435 {
436 key = "dPairGap";
437 aCfg->Read( key << idx, &gap );
438
439 key = "dPairViaGap";
440 aCfg->Read( key << idx, &via_gap );
441
442 nlohmann::json pair = { { "width", width }, { "gap", gap }, { "via_gap", via_gap } };
443 pairs.push_back( pair );
444
445 key = keyBase;
446 key << ++idx;
447 }
448
449 Set( bp + "diff_pair_dimensions", pairs );
450 }
451
452 group_blacklist.insert( wxT( "/pcbnew" ) );
453
454 // General group is unused these days, we can throw it away
455 group_blacklist.insert( wxT( "/general" ) );
456
457 // Next load sheet names and put all other legacy data in the legacy dict
458 aCfg->SetPath( wxT( "/" ) );
459
460 auto loadSheetNames =
461 [&]() -> bool
462 {
463 int sheet = 1;
464 wxString entry;
465 nlohmann::json arr = nlohmann::json::array();
466
467 wxLogTrace( traceSettings, wxT( "Migrating sheet names" ) );
468
469 aCfg->SetPath( wxT( "/sheetnames" ) );
470
471 while( aCfg->Read( wxString::Format( "%d", sheet++ ), &entry ) )
472 {
473 wxArrayString tokens = wxSplit( entry, ':' );
474
475 if( tokens.size() == 2 )
476 {
477 wxLogTrace( traceSettings, wxT( "%d: %s = %s" ), sheet, tokens[0],
478 tokens[1] );
479 arr.push_back( nlohmann::json::array( { tokens[0], tokens[1] } ) );
480 }
481 }
482
483 Set( "sheets", arr );
484
485 aCfg->SetPath( "/" );
486
487 // TODO: any reason we want to fail on this?
488 return true;
489 };
490
491 std::vector<wxString> groups;
492
493 groups.emplace_back( wxEmptyString );
494
495 auto loadLegacyPairs =
496 [&]( const std::string& aGroup ) -> bool
497 {
498 wxLogTrace( traceSettings, wxT( "Migrating group %s" ), aGroup );
499 bool success = true;
500 wxString keyStr;
501 wxString val;
502
503 index = 0;
504
505 while( aCfg->GetNextEntry( keyStr, index ) )
506 {
507 if( !aCfg->Read( keyStr, &val ) )
508 continue;
509
510 std::string key( keyStr.ToUTF8() );
511
512 wxLogTrace( traceSettings, wxT( " %s = %s" ), key, val );
513
514 try
515 {
516 Set( "legacy." + aGroup + "." + key, val );
517 }
518 catch( ... )
519 {
520 success = false;
521 }
522 }
523
524 return success;
525 };
526
527 for( size_t i = 0; i < groups.size(); i++ )
528 {
529 aCfg->SetPath( groups[i] );
530
531 if( groups[i] == wxT( "/sheetnames" ) )
532 {
533 ret |= loadSheetNames();
534 continue;
535 }
536
537 aCfg->DeleteEntry( wxT( "last_client" ), true );
538 aCfg->DeleteEntry( wxT( "update" ), true );
539 aCfg->DeleteEntry( wxT( "version" ), true );
540
541 ret &= loadLegacyPairs( groups[i].ToStdString() );
542
543 index = 0;
544
545 while( aCfg->GetNextGroup( str, index ) )
546 {
547 wxString group = groups[i] + "/" + str;
548
549 if( !group_blacklist.count( group ) )
550 groups.emplace_back( group );
551 }
552
553 aCfg->SetPath( "/" );
554 }
555
556 return ret;
557}
558
559
560bool PROJECT_FILE::SaveToFile( const wxString& aDirectory, bool aForce )
561{
562 wxASSERT( m_project );
563
564 Set( "meta.filename", m_project->GetProjectName() + "." + ProjectFileExtension );
565
566 return JSON_SETTINGS::SaveToFile( aDirectory, aForce );
567}
568
569
570bool PROJECT_FILE::SaveAs( const wxString& aDirectory, const wxString& aFile )
571{
572 wxFileName oldFilename( GetFilename() );
573 wxString oldProjectName = oldFilename.GetName();
574
575 Set( "meta.filename", aFile + "." + ProjectFileExtension );
576 SetFilename( aFile );
577
578 auto updatePath =
579 [&]( wxString& aPath )
580 {
581 if( aPath.StartsWith( oldProjectName + wxS( "." ) ) )
582 aPath.Replace( oldProjectName, aFile, false );
583 };
584
585 updatePath( m_PcbLastPath[ LAST_PATH_NETLIST ] );
586 updatePath( m_PcbLastPath[ LAST_PATH_STEP ] );
587 updatePath( m_PcbLastPath[ LAST_PATH_IDF ] );
588 updatePath( m_PcbLastPath[ LAST_PATH_VRML ] );
589 updatePath( m_PcbLastPath[ LAST_PATH_SPECCTRADSN ] );
590 updatePath( m_PcbLastPath[ LAST_PATH_GENCAD ] );
591
592 // While performing Save As, we have already checked that we can write to the directory
593 // so don't carry the previous flag
594 SetReadOnly( false );
595 return JSON_SETTINGS::SaveToFile( aDirectory, true );
596}
597
598
600{
602}
603
604
606{
608}
609
610
611void to_json( nlohmann::json& aJson, const FILE_INFO_PAIR& aPair )
612{
613 aJson = nlohmann::json::array( { aPair.first.AsString().ToUTF8(), aPair.second.ToUTF8() } );
614}
615
616
617void from_json( const nlohmann::json& aJson, FILE_INFO_PAIR& aPair )
618{
619 wxCHECK( aJson.is_array() && aJson.size() == 2, /* void */ );
620 aPair.first = KIID( wxString( aJson[0].get<std::string>().c_str(), wxConvUTF8 ) );
621 aPair.second = wxString( aJson[1].get<std::string>().c_str(), wxConvUTF8 );
622}
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 SetReadOnly(bool aReadOnly)
Definition: json_settings.h:85
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
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...
bool m_deleteLegacyAfterMigration
Whether or not to delete legacy file after migration.
void SetFilename(const wxString &aFilename)
Definition: json_settings.h:77
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
wxString GetFilename() const
Definition: json_settings.h:73
Definition: kiid.h:48
Like a normal param, but with custom getter and setter functions.
Definition: parameters.h:282
Represents a list of strings holding directory paths.
Definition: parameters.h:489
Stores a path as a string with directory separators normalized to unix-style.
Definition: parameters.h:164
A helper for <wxString, wxString> maps.
Definition: parameters.h:580
std::map< wxString, wxString > m_TextVars
Definition: project_file.h:120
wxString getFileExt() const override
wxString m_LegacyLibDir
Definition: project_file.h:133
wxString m_BoardDrawingSheetFile
PcbNew params.
Definition: project_file.h:149
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
Definition: project_file.h:168
wxString m_PcbLastPath[LAST_PATH_SIZE]
MRU path storage.
Definition: project_file.h:152
PROJECT * m_project
A link to the owning PROJECT.
Definition: project_file.h:183
std::vector< VIEWPORT > m_Viewports
List of stored layer presets.
Definition: project_file.h:172
bool SaveAs(const wxString &aDirectory, const wxString &aFile)
std::vector< wxString > m_EquivalenceFiles
CvPcb params.
Definition: project_file.h:142
wxString getLegacyFileExt() const override
std::vector< wxString > m_PinnedFootprintLibs
The list of pinned footprint libraries.
Definition: project_file.h:118
std::vector< FILE_INFO_PAIR > m_sheets
List of stored 3D viewports (view matrixes)
Definition: project_file.h:177
virtual bool MigrateFromLegacy(wxConfigBase *aCfg) override
Migrates from wxConfig to JSON-based configuration.
std::vector< LAYER_PRESET > m_LayerPresets
Definition: project_file.h:171
std::vector< FILE_INFO_PAIR > m_boards
A list of board files in this project.
Definition: project_file.h:180
wxArrayString m_LegacyLibNames
Definition: project_file.h:135
std::vector< wxString > m_PinnedSymbolLibs
Below are project-level settings that have not been moved to a dedicated file.
Definition: project_file.h:115
std::vector< VIEWPORT3D > m_Viewports3D
List of stored viewports (pos + zoom)
Definition: project_file.h:173
bool SaveToFile(const wxString &aDirectory="", bool aForce=false) override
PROJECT_FILE(const wxString &aFullPath)
Construct the project file for a project.
Container for project specific data.
Definition: project.h:64
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:132
const std::string LegacyProjectFileExtension
const std::string ProjectFileExtension
const wxChar *const traceSettings
Flag to enable debug output of settings operations and management.
SETTINGS_LOC
Definition: json_settings.h:47
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
@ LAST_PATH_SPECCTRADSN
Definition: project_file.h:52
@ LAST_PATH_GENCAD
Definition: project_file.h:53
@ LAST_PATH_IDF
Definition: project_file.h:50
@ LAST_PATH_VRML
Definition: project_file.h:51
@ LAST_PATH_NETLIST
Definition: project_file.h:48
@ LAST_PATH_STEP
Definition: project_file.h:49
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...
Definition: project_file.h:41
Definition of file extensions used in Kicad.