KiCad PCB EDA Suite
Loading...
Searching...
No Matches
footprint_editor_settings.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 Jon Evans <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
22
26#include <common.h>
27#include <layer_ids.h>
28#include <lset.h>
29#include <pgm_base.h>
30#include <eda_text.h>
31#include <pcb_dimension.h>
34#include <settings/parameters.h>
37#include <base_units.h>
38
39#include <wx/config.h>
40#include <wx/log.h>
41
42
44const int fpEditSchemaVersion = 5;
45
46
49 m_DesignSettings( nullptr, "fpedit.settings" ),
51 m_Display(),
52 m_UserGrid(),
53 m_PolarCoords( false ),
54 m_DisplayInvertXAxis( false ),
55 m_DisplayInvertYAxis( false ),
58 m_AutoConstraints( true ),
60 m_LibWidth( 250 ),
62{
64
67 m_MagneticItems.graphics = true;
68 m_MagneticItems.allLayers = false;
69
70 m_AuiPanels.appearance_panel_tab = 0;
71 m_AuiPanels.right_panel_width = -1;
72 m_AuiPanels.show_layer_manager = true;
73
74 m_params.emplace_back( new PARAM<int>( "window.lib_width",
75 &m_LibWidth, 250 ) );
76
77 m_params.emplace_back( new PARAM<bool>( "aui.show_layer_manager",
78 &m_AuiPanels.show_layer_manager, true ) );
79
80 m_params.emplace_back( new PARAM<int>( "aui.right_panel_width",
81 &m_AuiPanels.right_panel_width, -1 ) );
82
83 m_params.emplace_back( new PARAM<int>( "aui.appearance_panel_tab",
84 &m_AuiPanels.appearance_panel_tab, 0, 0, 2 ) );
85
86 m_params.emplace_back( new PARAM<int>( "aui.properties_panel_width",
87 &m_AuiPanels.properties_panel_width, -1 ) );
88
89 m_params.emplace_back( new PARAM<float>( "aui.properties_splitter_proportion",
90 &m_AuiPanels.properties_splitter, 0.5f ) );
91
92 m_params.emplace_back( new PARAM<bool>( "aui.show_properties",
93 &m_AuiPanels.show_properties, true ) );
94
95 m_params.emplace_back( new PARAM<int>( "library.sort_mode",
96 &m_LibrarySortMode, 0 ) );
97
98 m_params.emplace_back( new PARAM<wxString>( "system.last_import_export_path",
99 &m_LastExportPath, "" ) );
100
101 m_params.emplace_back( new PARAM<bool>( "pcb_display.graphics_fill",
102 &m_ViewersDisplay.m_DisplayGraphicsFill, true ) );
103
104 m_params.emplace_back( new PARAM<bool>( "pcb_display.text_fill",
105 &m_ViewersDisplay.m_DisplayTextFill, true ) );
106
107 m_params.emplace_back( new PARAM<bool>( "pcb_display.pad_fill",
108 &m_ViewersDisplay.m_DisplayPadFill, true ) );
109
110 m_params.emplace_back( new PARAM<bool>( "pcb_display.pad_numbers",
111 &m_ViewersDisplay.m_DisplayPadNumbers, true ) );
112
113 m_params.emplace_back( new PARAM<int>( "editing.magnetic_pads",
114 reinterpret_cast<int*>( &m_MagneticItems.pads ),
115 static_cast<int>( MAGNETIC_OPTIONS::CAPTURE_ALWAYS ) ) );
116
117 m_params.emplace_back( new PARAM<bool>( "editing.magnetic_graphics",
118 &m_MagneticItems.graphics, true ) );
119
120 m_params.emplace_back( new PARAM<bool>( "editing.magnetic_all_layers",
121 &m_MagneticItems.allLayers, false ) );
122
124
125 m_params.emplace_back( new PARAM_MAP<int>( "lib_field_editor.field_widths",
126 &m_LibFieldEditor.field_widths, {} ) );
127
128 m_params.emplace_back( new PARAM<int>( "lib_field_editor.selection_mode",
129 &m_LibFieldEditor.selection_mode, 0 ) );
130
131 m_params.emplace_back( new PARAM<int>( "lib_field_editor.sash_pos",
132 &m_LibFieldEditor.sash_pos, 400 ) );
133
134 m_params.emplace_back( new PARAM<int>( "lib_field_editor.variant_sash_pos",
135 &m_LibFieldEditor.variant_sash_pos, 500 ) );
136
137 m_params.emplace_back( new PARAM<bool>( "lib_field_editor.sidebar_collapsed",
138 &m_LibFieldEditor.sidebar_collapsed, false ) );
139
140 m_params.emplace_back( new PARAM<wxString>( "lib_field_editor.bom_export_filename",
141 &m_LibFieldEditorBom.m_BomExportFileName, "${PROJECTNAME}.csv" ) );
142
143 m_params.emplace_back( new PARAM<BOM_PRESET>( "lib_field_editor.bom_settings",
144 &m_LibFieldEditorBom.m_BomSettings, {} ) );
145
146 m_params.emplace_back( new PARAM_LIST<BOM_PRESET>( "lib_field_editor.bom_presets",
147 &m_LibFieldEditorBom.m_BomPresets, {} ) );
148
149 m_params.emplace_back( new PARAM<BOM_FMT_PRESET>( "lib_field_editor.bom_fmt_settings",
150 &m_LibFieldEditorBom.m_BomFmtSettings, BOM_FMT_PRESET::CSV() ) );
151
152 m_params.emplace_back( new PARAM_LIST<BOM_FMT_PRESET>( "lib_field_editor.bom_fmt_presets",
153 &m_LibFieldEditorBom.m_BomFmtPresets, {} ) );
154
155 m_params.emplace_back( new PARAM<bool>( "editing.polar_coords",
156 &m_PolarCoords, false ) );
157
158 m_params.emplace_back( new PARAM<bool>( "origin_invert_x_axis",
159 &m_DisplayInvertXAxis, false ) );
160
161 m_params.emplace_back( new PARAM<bool>( "origin_invert_y_axis",
162 &m_DisplayInvertYAxis, false ) );
163
164 m_params.emplace_back( new PARAM_LAMBDA<int>( "editing.rotation_angle",
165 [this] () -> int
166 {
167 return m_RotationAngle.AsTenthsOfADegree();
168 },
169 [this] ( int aVal )
170 {
171 if( aVal )
173 },
174 900 ) );
175
176 m_params.emplace_back( new PARAM<int>( "editing.fp_angle_snap_mode",
177 reinterpret_cast<int*>( &m_AngleSnapMode ),
178 static_cast<int>( LEADER_MODE::DEG45 ) ) );
179
180 m_params.emplace_back( new PARAM<bool>( "editing.auto_constraints", &m_AutoConstraints, true ) );
181
182 m_params.emplace_back( new PARAM_LAYER_PRESET( "pcb_display.layer_presets", &m_LayerPresets ) );
183
184 m_params.emplace_back( new PARAM<wxString>( "pcb_display.active_layer_preset",
185 &m_ActiveLayerPreset, "" ) );
186
187 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "tabs.open",
188 [&]() -> nlohmann::json
189 {
190 nlohmann::json js = nlohmann::json::array();
191
192 for( const OPEN_TAB& tab : m_OpenTabs )
193 {
194 js.push_back( nlohmann::json( { { "lib", tab.m_lib.ToUTF8() },
195 { "fp_name", tab.m_fpName.ToUTF8() },
196 { "preview", tab.m_preview } } ) );
197 }
198
199 return js;
200 },
201 [&]( const nlohmann::json& aObj )
202 {
203 m_OpenTabs.clear();
204
205 if( !aObj.is_array() )
206 return;
207
208 for( const nlohmann::json& entry : aObj )
209 {
210 if( !entry.is_object() || !entry.contains( "lib" ) || !entry.contains( "fp_name" ) )
211 continue;
212
213 OPEN_TAB tab;
214 tab.m_lib = entry.at( "lib" ).get<wxString>();
215 tab.m_fpName = entry.at( "fp_name" ).get<wxString>();
216
217 // Older configs predate the preview flag and default to a permanent tab.
218 if( entry.contains( "preview" ) )
219 tab.m_preview = entry.at( "preview" ).get<bool>();
220
221 m_OpenTabs.push_back( std::move( tab ) );
222 }
223 },
224 nlohmann::json::array() ) );
225
226 m_params.emplace_back( new PARAM<wxString>( "tabs.active",
227 &m_ActiveTab, "" ) );
228
229 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>(
230 "design_settings.default_footprint_text_items",
231 [&] () -> nlohmann::json
232 {
233 nlohmann::json js = nlohmann::json::array();
234
235 for( const TEXT_ITEM_INFO& item : m_DesignSettings.m_DefaultFPTextItems )
236 {
237 js.push_back( nlohmann::json( { item.m_Text.ToUTF8(),
238 item.m_Visible,
239 LSET::Name( item.m_Layer ) } ) );
240 }
241
242 return js;
243 },
244 [&] ( const nlohmann::json& aObj )
245 {
246 m_DesignSettings.m_DefaultFPTextItems.clear();
247
248 if( !aObj.is_array() )
249 return;
250
251 for( const nlohmann::json& entry : aObj )
252 {
253 if( entry.empty() || !entry.is_array() )
254 continue;
255
256 TEXT_ITEM_INFO textInfo( wxT( "" ), true, F_SilkS );
257
258 textInfo.m_Text = entry.at(0).get<wxString>();
259 textInfo.m_Visible = entry.at(1).get<bool>();
260 wxString layerName = entry.at(2).get<wxString>();
261 int candidateLayer = LSET::NameToLayer( layerName );
262 textInfo.m_Layer = candidateLayer >= 0
263 ? static_cast<PCB_LAYER_ID>(candidateLayer)
264 : F_SilkS;
265
266 m_DesignSettings.m_DefaultFPTextItems.push_back( std::move( textInfo ) );
267 }
268 },
269 nlohmann::json::array( {
270 { "REF**", true, LSET::Name( F_SilkS ) },
271 { "", true, LSET::Name( F_Fab ) },
272 { "${REFERENCE}", true, LSET::Name( F_Fab ) }
273 } ) ) );
274
275 m_params.emplace_back( new PARAM_MAP<wxString>( "design_settings.default_footprint_layer_names",
276 &m_DesignSettings.m_UserLayerNames, {} ) );
277
278 m_params.emplace_back( new PARAM_LAMBDA<int>( "design_settings.user_layer_count",
279 [this]() { return m_DesignSettings.GetUserDefinedLayerCount(); },
280 [this]( int aCount ) { m_DesignSettings.SetUserDefinedLayerCount( aCount ); },
281 4 ) );
282
283 int minTextSize = pcbIUScale.mmToIU( TEXT_MIN_SIZE_MM );
284 int maxTextSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
285 int minStroke = 1;
286 int maxStroke = pcbIUScale.mmToIU( 100 );
287
288 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_line_width",
289 &m_DesignSettings.m_LineThickness[ LAYER_CLASS_SILK ],
290 pcbIUScale.mmToIU( DEFAULT_SILK_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
291
292 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_text_size_h",
293 &m_DesignSettings.m_TextSize[ LAYER_CLASS_SILK ].x,
294 pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
295
296 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_text_size_v",
297 &m_DesignSettings.m_TextSize[ LAYER_CLASS_SILK ].y,
298 pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
299
300 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_text_thickness",
301 &m_DesignSettings.m_TextThickness[ LAYER_CLASS_SILK ],
302 pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_WIDTH ), 1, maxTextSize, pcbIUScale.MM_PER_IU ) );
303
304 m_params.emplace_back( new PARAM<bool>( "design_settings.silk_text_italic",
305 &m_DesignSettings.m_TextItalic[ LAYER_CLASS_SILK ], false ) );
306
307 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_line_width",
308 &m_DesignSettings.m_LineThickness[ LAYER_CLASS_COPPER ],
309 pcbIUScale.mmToIU( DEFAULT_COPPER_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
310
311 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_text_size_h",
312 &m_DesignSettings.m_TextSize[ LAYER_CLASS_COPPER ].x,
313 pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
314
315 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_text_size_v",
316 &m_DesignSettings.m_TextSize[ LAYER_CLASS_COPPER ].y,
317 pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
318
319 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_text_thickness",
320 &m_DesignSettings.m_TextThickness[ LAYER_CLASS_COPPER ],
321 pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
322
323 m_params.emplace_back( new PARAM<bool>( "design_settings.copper_text_italic",
324 &m_DesignSettings.m_TextItalic[ LAYER_CLASS_COPPER ], false ) );
325
326 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.edge_line_width",
327 &m_DesignSettings.m_LineThickness[ LAYER_CLASS_EDGES ],
328 pcbIUScale.mmToIU( DEFAULT_EDGE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
329
330 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.courtyard_line_width",
331 &m_DesignSettings.m_LineThickness[ LAYER_CLASS_COURTYARD ],
332 pcbIUScale.mmToIU( DEFAULT_COURTYARD_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
333
334 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_line_width",
335 &m_DesignSettings.m_LineThickness[ LAYER_CLASS_FAB ],
336 pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
337
338 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_text_size_h",
339 &m_DesignSettings.m_TextSize[ LAYER_CLASS_FAB ].x,
340 pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
341
342 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_text_size_v",
343 &m_DesignSettings.m_TextSize[ LAYER_CLASS_FAB ].y,
344 pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
345
346 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_text_thickness",
347 &m_DesignSettings.m_TextThickness[ LAYER_CLASS_FAB ],
348 pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ), 1, maxTextSize, pcbIUScale.MM_PER_IU ) );
349
350 m_params.emplace_back( new PARAM<bool>( "design_settings.fab_text_italic",
351 &m_DesignSettings.m_TextItalic[ LAYER_CLASS_FAB ], false ) );
352
353 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_line_width",
354 &m_DesignSettings.m_LineThickness[ LAYER_CLASS_OTHERS ],
355 pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
356
357 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_text_size_h",
358 &m_DesignSettings.m_TextSize[ LAYER_CLASS_OTHERS ].x,
359 pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
360
361 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_text_size_v",
362 &m_DesignSettings.m_TextSize[ LAYER_CLASS_OTHERS ].y,
363 pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
364
365 m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_text_thickness",
366 &m_DesignSettings.m_TextThickness[ LAYER_CLASS_OTHERS ],
367 pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ), 1, maxTextSize, pcbIUScale.MM_PER_IU ) );
368
369 m_params.emplace_back( new PARAM<bool>( "design_settings.others_text_italic",
370 &m_DesignSettings.m_TextItalic[ LAYER_CLASS_OTHERS ], false ) );
371
372
373 // ---------------------------------------------------------------------------------------------
374 // Dimension settings
375
376 m_params.emplace_back( new PARAM_ENUM<DIM_UNITS_MODE>( "design_settings.dimensions.units",
379
380 m_params.emplace_back( new PARAM_ENUM<DIM_PRECISION>( "design_settings.dimensions.precision",
382
383 m_params.emplace_back( new PARAM_ENUM<DIM_UNITS_FORMAT>( "design_settings.dimensions.units_format",
386
387 m_params.emplace_back( new PARAM<bool>( "design_settings.dimensions.suppress_zeroes",
388 &m_DesignSettings.m_DimensionSuppressZeroes, true ) );
389
390 // NOTE: excluding DIM_TEXT_POSITION::MANUAL from the valid range here
391 m_params.emplace_back( new PARAM_ENUM<DIM_TEXT_POSITION>( "design_settings.dimensions.text_position",
394
395 m_params.emplace_back( new PARAM<bool>( "design_settings.dimensions.keep_text_aligned",
396 &m_DesignSettings.m_DimensionKeepTextAligned, true ) );
397
398 m_params.emplace_back( new PARAM<int>( "design_settings.dimensions.arrow_length",
399 &m_DesignSettings.m_DimensionArrowLength,
401
402 m_params.emplace_back( new PARAM<int>( "design_settings.dimensions.extension_offset",
403 &m_DesignSettings.m_DimensionExtensionOffset,
405
406 // ---------------------------------------------------------------------------------------------
407
408 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "editing.selection_filter",
409 [&]() -> nlohmann::json
410 {
411 nlohmann::json ret;
412
413 ret["lockedItems"] = m_SelectionFilter.lockedItems;
414 ret["footprints"] = m_SelectionFilter.footprints;
415 ret["text"] = m_SelectionFilter.text;
416 ret["tracks"] = m_SelectionFilter.tracks;
417 ret["vias"] = m_SelectionFilter.vias;
418 ret["pads"] = m_SelectionFilter.pads;
419 ret["graphics"] = m_SelectionFilter.graphics;
420 ret["zones"] = m_SelectionFilter.zones;
421 ret["keepouts"] = m_SelectionFilter.keepouts;
422 ret["dimensions"] = m_SelectionFilter.dimensions;
423 ret["points"] = m_SelectionFilter.points;
424 ret["otherItems"] = m_SelectionFilter.otherItems;
425
426 return ret;
427 },
428 [&]( const nlohmann::json& aVal )
429 {
430 if( aVal.empty() || !aVal.is_object() )
431 return;
432
433 SetIfPresent( aVal, "lockedItems", m_SelectionFilter.lockedItems );
434 SetIfPresent( aVal, "footprints", m_SelectionFilter.footprints );
435 SetIfPresent( aVal, "text", m_SelectionFilter.text );
436 SetIfPresent( aVal, "tracks", m_SelectionFilter.tracks );
437 SetIfPresent( aVal, "vias", m_SelectionFilter.vias );
438 SetIfPresent( aVal, "pads", m_SelectionFilter.pads );
439 SetIfPresent( aVal, "graphics", m_SelectionFilter.graphics );
440 SetIfPresent( aVal, "zones", m_SelectionFilter.zones );
441 SetIfPresent( aVal, "keepouts", m_SelectionFilter.keepouts );
442 SetIfPresent( aVal, "dimensions", m_SelectionFilter.dimensions );
443 SetIfPresent( aVal, "points", m_SelectionFilter.points );
444 SetIfPresent( aVal, "otherItems", m_SelectionFilter.otherItems );
445 },
446 {
447 { "lockedItems", false },
448 { "footprints", true },
449 { "text", true },
450 { "tracks", true },
451 { "vias", true },
452 { "pads", true },
453 { "graphics", true },
454 { "zones", true },
455 { "keepouts", true },
456 { "dimensions", true },
457 { "points", true },
458 { "otherItems", true }
459 } ) );
460
462
463 registerMigration( 1, 2,
464 [&]() -> bool
465 {
466 // This is actually a migration for APP_SETTINGS_BASE::m_LibTree
467 return migrateLibTreeWidth();
468 } );
469
473}
474
475
477{
478 bool ret = APP_SETTINGS_BASE::MigrateFromLegacy( aCfg );
479
480 //
481 // NOTE: there's no value in line-wrapping these; it just makes the table unreadable.
482 //
483 ret &= fromLegacy<int>( aCfg, "ModeditLibWidth", "window.lib_width" );
484 ret &= fromLegacyString( aCfg, "import_last_path", "system.last_import_export_path" );
485
486 ret &= fromLegacy<int>( aCfg, "FpEditorMagneticPads", "editing.magnetic_pads" );
487 ret &= fromLegacy<bool>( aCfg, "FpEditorDisplayPolarCoords", "editing.polar_coords" );
488 ret &= fromLegacy<int>( aCfg, "FpEditorUse45DegreeGraphicSegments", "editing.use_45_degree_graphic_segments" );
489
490 ret &= fromLegacy<bool>( aCfg, "FpEditorGraphicLinesDisplayMode", "pcb_display.graphic_items_fill" );
491 ret &= fromLegacy<bool>( aCfg, "FpEditorPadDisplayMode", "pcb_display.pad_fill" );
492 ret &= fromLegacy<bool>( aCfg, "FpEditorTextsDisplayMode", "pcb_display.footprint_text" );
493
494 ret &= fromLegacy<double>( aCfg, "FpEditorSilkLineWidth", "design_settings.silk_line_width" );
495 ret &= fromLegacy<double>( aCfg, "FpEditorSilkTextSizeH", "design_settings.silk_text_size_h" );
496 ret &= fromLegacy<double>( aCfg, "FpEditorSilkTextSizeV", "design_settings.silk_text_size_v" );
497 ret &= fromLegacy<double>( aCfg, "FpEditorSilkTextThickness", "design_settings.silk_text_thickness" );
498 ret &= fromLegacy<bool>( aCfg, "FpEditorSilkTextItalic", "design_settings.silk_text_italic" );
499 ret &= fromLegacy<double>( aCfg, "FpEditorCopperLineWidth", "design_settings.copper_line_width" );
500 ret &= fromLegacy<double>( aCfg, "FpEditorCopperTextSizeH", "design_settings.copper_text_size_h" );
501 ret &= fromLegacy<double>( aCfg, "FpEditorCopperTextSizeV", "design_settings.copper_text_size_v" );
502 ret &= fromLegacy<double>( aCfg, "FpEditorCopperTextThickness", "design_settings.copper_text_thickness" );
503 ret &= fromLegacy<bool>( aCfg, "FpEditorCopperTextItalic", "design_settings.copper_text_italic" );
504 ret &= fromLegacy<double>( aCfg, "FpEditorEdgeCutLineWidth", "design_settings.edge_line_width" );
505 ret &= fromLegacy<double>( aCfg, "FpEditorCourtyardLineWidth", "design_settings.courtyard_line_width" );
506 ret &= fromLegacy<double>( aCfg, "FpEditorOthersLineWidth", "design_settings.others_line_width" );
507 ret &= fromLegacy<double>( aCfg, "FpEditorOthersTextSizeH", "design_settings.others_text_size_h" );
508 ret &= fromLegacy<double>( aCfg, "FpEditorOthersTextSizeV", "design_settings.others_text_size_v" );
509 ret &= fromLegacy<double>( aCfg, "FpEditorOthersTextThickness", "design_settings.others_text_thickness" );
510 ret &= fromLegacy<bool>( aCfg, "FpEditorOthersTextItalic", "design_settings.others_text_italic" );
511
512 nlohmann::json textItems = nlohmann::json::array( {
513 { "REF**", true, F_SilkS },
514 { "", true, F_Fab }
515 } );
516
517 Set( "design_settings.default_footprint_text_items", std::move( textItems ) );
518
519 ret &= fromLegacyString( aCfg, "FpEditorRefDefaultText", "design_settings.default_footprint_text_items.0.0" );
520 ret &= fromLegacy<bool>( aCfg, "FpEditorRefDefaultVisibility", "design_settings.default_footprint_text_items.0.1" );
521 ret &= fromLegacy<int>( aCfg, "FpEditorRefDefaultLayer", "design_settings.default_footprint_text_items.0.2" );
522 ret &= fromLegacyString( aCfg, "FpEditorValueDefaultText", "design_settings.default_footprint_text_items.1.0" );
523 ret &= fromLegacy<bool>( aCfg, "FpEditorValueDefaultVisibility", "design_settings.default_footprint_text_items.1.1" );
524 ret &= fromLegacy<int>( aCfg, "FpEditorValueDefaultLayer", "design_settings.default_footprint_text_items.1.2" );
525
526
527 std::string f = "ModEdit";
528
529 // Migrate color settings that were stored in the pcbnew config file
530 // We create a copy of the user scheme for the footprint editor context
531
533 COLOR_SETTINGS* cs = manager.AddNewColorSettings( "user_footprints" );
534
535 cs->SetName( wxT( "User (Footprints)" ) );
536 manager.Save( cs );
537
538 auto migrateLegacyColor = [&] ( const std::string& aKey, int aLayerId )
539 {
540 wxString str;
541
542 if( aCfg->Read( aKey, &str ) )
543 cs->SetColor( aLayerId, COLOR4D( str ) );
544 };
545
546 for( int i = 0; i < PCB_LAYER_ID_COUNT; ++i )
547 {
548 wxString layer = LSET::Name( PCB_LAYER_ID( i ) );
549 migrateLegacyColor( f + "Color4DPCBLayer_" + layer.ToStdString(), PCB_LAYER_ID( i ) );
550 }
551
552 migrateLegacyColor( f + "Color4DAnchorEx", LAYER_ANCHOR );
553 migrateLegacyColor( f + "Color4DAuxItems", LAYER_AUX_ITEMS );
554 migrateLegacyColor( f + "Color4DGrid", LAYER_GRID );
555 migrateLegacyColor( f + "Color4DNonPlatedEx", LAYER_NON_PLATEDHOLES );
556 migrateLegacyColor( f + "Color4DPCBBackground", LAYER_PCB_BACKGROUND );
557 migrateLegacyColor( f + "Color4DPCBCursor", LAYER_CURSOR );
558 migrateLegacyColor( f + "Color4DRatsEx", LAYER_RATSNEST );
559 migrateLegacyColor( f + "Color4DViaBBlindEx", LAYER_VIA_BLIND );
560 migrateLegacyColor( f + "Color4DViaBBlindEx", LAYER_VIA_BURIED );
561 migrateLegacyColor( f + "Color4DViaMicroEx", LAYER_VIA_MICROVIA );
562 migrateLegacyColor( f + "Color4DViaThruEx", LAYER_VIA_THROUGH );
563 migrateLegacyColor( f + "Color4DWorksheet", LAYER_DRAWINGSHEET );
564
565 manager.SaveColorSettings( cs, "board" );
566
567 ( *m_internals )[m_internals->PointerFromString( "appearance.color_theme" )] = "user_footprints";
568
569 double x = 0, y = 0;
570 f = "ModEditFrame";
571
572 if( aCfg->Read( f + "PcbUserGrid_X", &x ) && aCfg->Read( f + "PcbUserGrid_Y", &y ) )
573 {
574 EDA_UNITS u = static_cast<EDA_UNITS>( aCfg->ReadLong( f + "PcbUserGrid_Unit",
575 static_cast<long>( EDA_UNITS::INCH ) ) );
576
577 // Convert to internal units
580
581 Set( "window.grid.user_grid_x", EDA_UNIT_UTILS::UI::StringFromValue( pcbIUScale, u, x ) );
582 Set( "window.grid.user_grid_y", EDA_UNIT_UTILS::UI::StringFromValue( pcbIUScale, u, y ) );
583 }
584
585 return ret;
586}
587
588
590{
597
598 if( !m_manager )
599 {
600 wxLogTrace( traceSettings,
601 wxT( "Error: FOOTPRINT_EDITOR_SETTINGS migration cannot run unmanaged!" ) );
602 return false;
603 }
604
605 std::string theme_ptr( "appearance.color_theme" );
606
607 if( !Contains( theme_ptr ) )
608 return true;
609
610 wxString selected = At( theme_ptr ).get<wxString>();
611 wxString search = selected + wxT( "_footprints" );
612
613 for( COLOR_SETTINGS* settings : Pgm().GetSettingsManager().GetColorSettingsList() )
614 {
615 if( settings->GetFilename() == search )
616 {
617 wxLogTrace( traceSettings, wxT( "Updating footprint editor theme from %s to %s" ),
618 selected, search );
619 Set( theme_ptr, search );
620 return true;
621 }
622 }
623
624 return true;
625}
626
627
633{
634 auto p( "/pcb_display/layer_presets"_json_pointer );
635
636 if( !m_internals->contains( p ) || !m_internals->at( p ).is_array() )
637 return true;
638
639 nlohmann::json& presets = m_internals->at( p );
640
641 for( nlohmann::json& entry : presets )
643
644 return true;
645}
646
647
652{
653 auto p( "/pcb_display/layer_presets"_json_pointer );
654
655 if( !m_internals->contains( p ) || !m_internals->at( p ).is_array() )
656 return true;
657
658 nlohmann::json& presets = m_internals->at( p );
659
660 for( nlohmann::json& entry : presets )
662
663 return true;
664}
665
666
671{
672 auto p( "/design_settings/default_footprint_text_items"_json_pointer );
673
674 if( !m_internals->contains( p ) || !m_internals->at( p ).is_array() )
675 return true;
676
677 nlohmann::json& defaults = m_internals->at( p );
678
679 bool reset = false;
680
681 for( nlohmann::json& entry : defaults )
682 {
683 TEXT_ITEM_INFO textInfo( wxT( "" ), true, F_SilkS );
684
685 textInfo.m_Text = entry.at(0).get<wxString>();
686 textInfo.m_Visible = entry.at(1).get<bool>();
687 textInfo.m_Layer = static_cast<PCB_LAYER_ID>( entry.at(2).get<int>() );
688
689 if( textInfo.m_Layer == Rescue || textInfo.m_Layer >= User_5 )
690 {
691 // KiCad pre-9.0 nightlies would write buggy preferences out with invalid layers.
692 // If we detect that, reset to defaults
693 reset = true;
694 }
695 else
696 {
697 // Coming from 8.0 or earlier, just migrate to named layers
698 entry.at(2) = LSET::Name( textInfo.m_Layer );
699 }
700 }
701
702 if( reset )
703 {
704 defaults = nlohmann::json::array( {
705 { "REF**", true, LSET::Name( F_SilkS ) },
706 { "", true, LSET::Name( F_Fab ) },
707 { "${REFERENCE}", true, LSET::Name( F_Fab ) }
708 } );
709 }
710
711 return true;
712}
ARC_EDIT_MODE
Settings for arc editing.
@ KEEP_CENTER_ADJUST_ANGLE_RADIUS
When editing endpoints, the angle and radius are adjusted.
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:128
@ LAYER_CLASS_OTHERS
@ LAYER_CLASS_FAB
@ LAYER_CLASS_COURTYARD
@ LAYER_CLASS_SILK
@ LAYER_CLASS_COPPER
@ LAYER_CLASS_EDGES
#define DEFAULT_TEXT_WIDTH
#define DEFAULT_COPPER_TEXT_WIDTH
#define DEFAULT_DIMENSION_EXTENSION_OFFSET
#define DEFAULT_DIMENSION_ARROW_LENGTH
#define DEFAULT_SILK_TEXT_SIZE
#define DEFAULT_COPPER_LINE_WIDTH
#define DEFAULT_SILK_LINE_WIDTH
#define DEFAULT_SILK_TEXT_WIDTH
#define DEFAULT_EDGE_WIDTH
#define DEFAULT_COPPER_TEXT_SIZE
#define DEFAULT_LINE_WIDTH
#define DEFAULT_COURTYARD_WIDTH
virtual bool MigrateFromLegacy(wxConfigBase *aCfg) override
Migrates from wxConfig to JSON-based configuration.
bool migrateLibTreeWidth()
Migrate the library tree width setting from a single column (Item) to multi-column.
Color settings are a bit different than most of the settings objects in that there can be more than o...
void SetName(const wxString &aName)
void SetColor(int aLayer, const COLOR4D &aColor)
bool migrateSchema3To4()
Schema version 4: move layer presets to use named render layers.
BOARD_DESIGN_SETTINGS m_DesignSettings
Only some of these settings are actually used for footprint editing.
bool migrateSchema2To3()
Schema version 2: Bump for KiCad 9 layer numbering changes Migrate layer presets to use new enum valu...
wxString m_ActiveTab
Tab key ("lib:fpName") of the tab that was active when the editor last closed.
std::vector< LAYER_PRESET > m_LayerPresets
FIELDS_TABLE_SETTINGS m_LibFieldEditor
bool migrateSchema4To5()
Schema version 5: move text defaults to used named layers.
virtual bool MigrateFromLegacy(wxConfigBase *aLegacyConfig) override
Migrates from wxConfig to JSON-based configuration.
FIELDS_TABLE_BOM_SETTINGS m_LibFieldEditorBom
SNAP_INFERENCE_SETTINGS m_SnapInference
PCB_SELECTION_FILTER_OPTIONS m_SelectionFilter
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...
SETTINGS_MANAGER * m_manager
A pointer to the settings manager managing this file (may be null)
bool Contains(const std::string &aPath) const
static bool SetIfPresent(const nlohmann::json &aObj, const std::string &aPath, wxString &aTarget)
Sets the given string if the given key/path is present.
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.
nlohmann::json & At(const std::string &aPath)
Wrappers for the underlying JSON API so that most consumers don't need json.hpp All of these function...
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
Definition lset.cpp:113
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:184
Stores an enum as an integer.
Definition parameters.h:232
Like a normal param, but with custom getter and setter functions.
Definition parameters.h:299
static void MigrateToV9Layers(nlohmann::json &aJson)
static void MigrateToNamedRenderLayers(nlohmann::json &aJson)
Represents a map of <std::string, Value>.
Definition parameters.h:752
Represents a parameter that has a scaling factor between the value in the file and the value used int...
Definition parameters.h:410
PCB_VIEWERS_SETTINGS_BASE(const std::string &aFilename, int aSchemaVersion)
VIEWERS_DISPLAY_OPTIONS m_ViewersDisplay
void addMatchPropertiesParam()
Opt-in.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:123
void SaveColorSettings(COLOR_SETTINGS *aSettings, const std::string &aNamespace="")
Safely save a COLOR_SETTINGS to disk, preserving any changes outside the given namespace.
COLOR_SETTINGS * AddNewColorSettings(const wxString &aFilename)
Register a new color settings object with the given filename.
#define DEFAULT_TEXT_SIZE
The default text size in mils. (can be changed in preference menu)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:450
@ TENTHS_OF_A_DEGREE_T
Definition eda_angle.h:29
#define TEXT_MIN_SIZE_MM
Minimum text size (1 micron).
Definition eda_text.h:61
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition eda_text.h:62
EDA_UNITS
Definition eda_units.h:44
const int fpEditSchemaVersion
! Update the schema version whenever a migration is required
LEADER_MODE
The kind of the leader line.
@ DEG45
45 Degree only
#define traceSettings
@ LAYER_GRID
Definition layer_ids.h:250
@ LAYER_NON_PLATEDHOLES
Draw usual through hole vias.
Definition layer_ids.h:235
@ LAYER_DRAWINGSHEET
Sheet frame and title block.
Definition layer_ids.h:274
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition layer_ids.h:277
@ LAYER_CURSOR
PCB cursor.
Definition layer_ids.h:278
@ LAYER_AUX_ITEMS
Auxiliary items (guides, rule, etc).
Definition layer_ids.h:279
@ LAYER_RATSNEST
Definition layer_ids.h:249
@ LAYER_ANCHOR
Anchor of items having an anchor point (texts, footprints).
Definition layer_ids.h:244
@ LAYER_VIA_BURIED
Draw blind vias.
Definition layer_ids.h:231
@ LAYER_VIA_BLIND
Draw micro vias.
Definition layer_ids.h:230
@ LAYER_VIA_MICROVIA
Definition layer_ids.h:229
@ LAYER_VIA_THROUGH
Draw buried vias.
Definition layer_ids.h:232
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ User_5
Definition layer_ids.h:124
@ F_Fab
Definition layer_ids.h:115
@ F_SilkS
Definition layer_ids.h:96
@ Rescue
Definition layer_ids.h:117
@ PCB_LAYER_ID_COUNT
Definition layer_ids.h:167
KICOMMON_API double FromUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Return in internal units the value aValue given in a real unit such as "in", "mm",...
KICOMMON_API wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Return the string from aValue according to aUnits (inch, mm ...) for display.
@ OUTSIDE
Text appears outside the dimension line (default)
@ INLINE
Text appears in line with the dimension line.
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
void AddSnapInferenceParams(std::vector< PARAM_BASE * > &aParams, SNAP_INFERENCE_SETTINGS &aSettings)
Register the snap inference parameters.
static BOM_FMT_PRESET CSV()
One open tab persisted across sessions.