You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

836 lines
38 KiB

5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <pybind11/pybind11.h>
  24. #include <common.h>
  25. #include <footprint_editor_settings.h>
  26. #include <layer_ids.h>
  27. #include <pcbnew_settings.h>
  28. #include <pgm_base.h>
  29. #include <router/pns_routing_settings.h>
  30. #include <settings/common_settings.h>
  31. #include <settings/nested_settings.h>
  32. #include <settings/parameters.h>
  33. #include <settings/settings_manager.h>
  34. #include <wx/config.h>
  35. #include <wx/tokenzr.h>
  36. #include <zones.h>
  37. #include <widgets/ui_common.h>
  38. #include <base_units.h>
  39. #include "../3d-viewer/3d_viewer/eda_3d_viewer_settings.h"
  40. ///! Update the schema version whenever a migration is required
  41. const int pcbnewSchemaVersion = 1;
  42. PCBNEW_SETTINGS::PCBNEW_SETTINGS()
  43. : APP_SETTINGS_BASE( "pcbnew", pcbnewSchemaVersion ),
  44. m_AuiPanels(),
  45. m_Cleanup(),
  46. m_DrcDialog(),
  47. m_ExportIdf(),
  48. m_ExportStep(),
  49. m_ExportSvg(),
  50. m_ExportVrml(),
  51. m_FootprintWizardList(),
  52. m_GenDrill(),
  53. m_ImportGraphics(),
  54. m_NetlistDialog(),
  55. m_PlaceFile(),
  56. m_Plot(),
  57. m_FootprintChooser(),
  58. m_Zones(),
  59. m_FootprintViewer(),
  60. m_FootprintWizard(),
  61. m_Display(),
  62. m_TrackDragAction( TRACK_DRAG_ACTION::DRAG ),
  63. m_PcbUse45DegreeLimit( false ),
  64. m_FpeditUse45DegreeLimit( false ),
  65. m_FlipLeftRight( false ),
  66. m_PolarCoords( false ),
  67. m_RotationAngle( 900 ),
  68. m_ShowPageLimits( true ),
  69. m_AutoRefillZones( true ),
  70. m_AllowFreePads( false ),
  71. m_PnsSettings( nullptr ),
  72. m_FootprintViewerZoom( 1.0 )
  73. {
  74. m_MagneticItems.pads = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL;
  75. m_MagneticItems.tracks = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL;
  76. m_MagneticItems.graphics = false;
  77. m_params.emplace_back( new PARAM<bool>( "aui.show_layer_manager",
  78. &m_AuiPanels.show_layer_manager, true ) );
  79. m_params.emplace_back( new PARAM<int>( "aui.right_panel_width",
  80. &m_AuiPanels.right_panel_width, -1 ) );
  81. m_params.emplace_back( new PARAM<int>( "aui.appearance_panel_tab",
  82. &m_AuiPanels.appearance_panel_tab, 0, 0, 2 ) );
  83. m_params.emplace_back( new PARAM<int>( "footprint_chooser.width",
  84. &m_FootprintChooser.width, -1 ) );
  85. m_params.emplace_back( new PARAM<int>( "footprint_chooser.height",
  86. &m_FootprintChooser.height, -1 ) );
  87. m_params.emplace_back( new PARAM<int>( "footprint_chooser.sash_h",
  88. &m_FootprintChooser.sash_h, -1 ) );
  89. m_params.emplace_back( new PARAM<int>( "footprint_chooser.sash_v",
  90. &m_FootprintChooser.sash_v, -1 ) );
  91. m_params.emplace_back( new PARAM<bool>( "editing.flip_left_right",
  92. &m_FlipLeftRight, true ) );
  93. m_params.emplace_back( new PARAM<bool>( "editing.magnetic_graphics",
  94. &m_MagneticItems.graphics, true ) );
  95. m_params.emplace_back( new PARAM<int>( "editing.magnetic_pads",
  96. reinterpret_cast<int*>( &m_MagneticItems.pads ),
  97. static_cast<int>( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ) ) );
  98. m_params.emplace_back( new PARAM<int>( "editing.magnetic_tracks",
  99. reinterpret_cast<int*>( &m_MagneticItems.tracks ),
  100. static_cast<int>( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ) ) );
  101. m_params.emplace_back( new PARAM<bool>( "editing.polar_coords",
  102. &m_PolarCoords, false ) );
  103. m_params.emplace_back( new PARAM<int>( "editing.track_drag_action",
  104. reinterpret_cast<int*>( &m_TrackDragAction ),
  105. static_cast<int>( TRACK_DRAG_ACTION::DRAG ) ) );
  106. m_params.emplace_back( new PARAM<bool>( "editing.pcb_use_45_degree_limit",
  107. &m_PcbUse45DegreeLimit, false ) );
  108. m_params.emplace_back( new PARAM<bool>( "editing.fp_use_45_degree_limit",
  109. &m_FpeditUse45DegreeLimit, false ) );
  110. m_params.emplace_back( new PARAM<bool>( "editing.auto_fill_zones",
  111. &m_AutoRefillZones, true ) );
  112. m_params.emplace_back( new PARAM<bool>( "editing.allow_free_pads",
  113. &m_AllowFreePads, false ) );
  114. m_params.emplace_back( new PARAM<int>( "editing.rotation_angle",
  115. &m_RotationAngle, 900, 1, 900 ) );
  116. m_params.emplace_back( new PARAM<bool>( "pcb_display.graphic_items_fill",
  117. &m_Display.m_DisplayGraphicsFill, true ) );
  118. m_params.emplace_back( new PARAM<int>( "pcb_display.max_links_shown",
  119. &m_Display.m_MaxLinksShowed, 3, 0, 15 ) );
  120. m_params.emplace_back( new PARAM<bool>( "pcb_display.graphics_fill",
  121. &m_Display.m_DisplayGraphicsFill, true ) );
  122. m_params.emplace_back( new PARAM<bool>( "pcb_display.text_fill",
  123. &m_Display.m_DisplayTextFill, true ) );
  124. m_params.emplace_back( new PARAM<int>( "pcb_display.net_names_mode",
  125. &m_Display.m_DisplayNetNamesMode, 3, 0, 3 ) );
  126. m_params.emplace_back( new PARAM<bool>( "pcb_display.pad_clearance",
  127. &m_Display.m_DisplayPadClearance, true ) );
  128. m_params.emplace_back( new PARAM<bool>( "pcb_display.pad_no_connects",
  129. &m_Display.m_DisplayPadNoConnects, true ) );
  130. m_params.emplace_back( new PARAM<bool>( "pcb_display.pad_fill",
  131. &m_Display.m_DisplayPadFill, true ) );
  132. m_params.emplace_back( new PARAM<bool>( "pcb_display.pad_numbers",
  133. &m_Display.m_DisplayPadNum, true ) );
  134. m_params.emplace_back( new PARAM<bool>( "pcb_display.ratsnest_global",
  135. &m_Display.m_ShowGlobalRatsnest, true ) );
  136. m_params.emplace_back( new PARAM<bool>( "pcb_display.ratsnest_footprint",
  137. &m_Display.m_ShowModuleRatsnest, true ) );
  138. m_params.emplace_back( new PARAM<bool>( "pcb_display.ratsnest_curved",
  139. &m_Display.m_DisplayRatsnestLinesCurved, false ) );
  140. m_params.emplace_back( new PARAM<int>( "pcb_display.track_clearance_mode",
  141. reinterpret_cast<int*>( &m_Display.m_ShowTrackClearanceMode ),
  142. PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WITH_VIA_WHILE_ROUTING ) );
  143. m_params.emplace_back( new PARAM<bool>( "pcb_display.track_fill",
  144. &m_Display.m_DisplayPcbTrackFill, true ) );
  145. m_params.emplace_back( new PARAM<bool>( "pcb_display.via_fill",
  146. &m_Display.m_DisplayViaFill, true ) );
  147. m_params.emplace_back( new PARAM_ENUM<ZONE_DISPLAY_MODE>( "pcb_display.zone_mode",
  148. &m_Display.m_ZoneDisplayMode, ZONE_DISPLAY_MODE::SHOW_FILLED,
  149. ZONE_DISPLAY_MODE::SHOW_TRIANGULATION, ZONE_DISPLAY_MODE::SHOW_FILLED ) );
  150. m_params.emplace_back( new PARAM<int>( "pcb_display.origin_mode",
  151. reinterpret_cast<int*>( &m_Display.m_DisplayOrigin ),
  152. PCB_DISPLAY_OPTIONS::PCB_ORIGIN_PAGE ) );
  153. m_params.emplace_back( new PARAM<bool>( "pcb_display.origin_invert_x_axis",
  154. &m_Display.m_DisplayInvertXAxis, false ) );
  155. m_params.emplace_back( new PARAM<bool>( "pcb_display.origin_invert_y_axis",
  156. &m_Display.m_DisplayInvertYAxis, false ) );
  157. m_params.emplace_back( new PARAM<bool>( "pcb_display.live_3d_refresh",
  158. &m_Display.m_Live3DRefresh, false ) );
  159. m_params.emplace_back( new PARAM<bool>( "pcb_display.show_page_borders",
  160. &m_ShowPageLimits, true ) );
  161. m_params.emplace_back( new PARAM<bool>( "cleanup.cleanup_vias",
  162. &m_Cleanup.cleanup_vias, true ) );
  163. m_params.emplace_back( new PARAM<bool>( "cleanup.delete_dangling_vias",
  164. &m_Cleanup.delete_dangling_vias, true ) );
  165. m_params.emplace_back( new PARAM<bool>( "cleanup.merge_segments",
  166. &m_Cleanup.merge_segments, true ) );
  167. m_params.emplace_back( new PARAM<bool>( "cleanup.cleanup_unconnected",
  168. &m_Cleanup.cleanup_unconnected, true ) );
  169. m_params.emplace_back( new PARAM<bool>( "cleanup.cleanup_short_circuits",
  170. &m_Cleanup.cleanup_short_circuits, true ) );
  171. m_params.emplace_back( new PARAM<bool>( "cleanup.cleanup_tracks_in_pad",
  172. &m_Cleanup.cleanup_tracks_in_pad, false ) );
  173. m_params.emplace_back( new PARAM<bool>( "drc_dialog.refill_zones",
  174. &m_DrcDialog.refill_zones, true ) );
  175. m_params.emplace_back( new PARAM<bool>( "drc_dialog.test_all_track_errors",
  176. &m_DrcDialog.test_all_track_errors, false ) );
  177. m_params.emplace_back( new PARAM<bool>( "drc_dialog.test_footprints",
  178. &m_DrcDialog.test_footprints, false ) );
  179. m_params.emplace_back( new PARAM<int>( "drc_dialog.severities",
  180. &m_DrcDialog.severities, RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ) );
  181. m_params.emplace_back( new PARAM<bool>( "gen_drill.merge_pth_npth",
  182. &m_GenDrill.merge_pth_npth, false ) );
  183. m_params.emplace_back( new PARAM<bool>( "gen_drill.minimal_header",
  184. &m_GenDrill.minimal_header, false ) );
  185. m_params.emplace_back( new PARAM<bool>( "gen_drill.mirror",
  186. &m_GenDrill.mirror, false ) );
  187. m_params.emplace_back( new PARAM<bool>( "gen_drill.unit_drill_is_inch",
  188. &m_GenDrill.unit_drill_is_inch, true ) );
  189. m_params.emplace_back( new PARAM<bool>( "gen_drill.use_route_for_oval_holes",
  190. &m_GenDrill.use_route_for_oval_holes, true ) );
  191. m_params.emplace_back( new PARAM<int>( "gen_drill.drill_file_type",
  192. &m_GenDrill.drill_file_type, 0 ) );
  193. m_params.emplace_back( new PARAM<int>( "gen_drill.map_file_type",
  194. &m_GenDrill.map_file_type, 1 ) );
  195. m_params.emplace_back( new PARAM<int>( "gen_drill.zeros_format",
  196. &m_GenDrill.zeros_format, 0, 0, 3 ) );
  197. m_params.emplace_back( new PARAM<bool>( "export_idf.auto_adjust",
  198. &m_ExportIdf.auto_adjust, false ) );
  199. m_params.emplace_back( new PARAM<int>( "export_idf.ref_units",
  200. &m_ExportIdf.ref_units, 0 ) );
  201. m_params.emplace_back( new PARAM<double>( "export_idf.ref_x",
  202. &m_ExportIdf.ref_x, 0 ) );
  203. m_params.emplace_back( new PARAM<double>( "export_idf.ref_y",
  204. &m_ExportIdf.ref_y, 0 ) );
  205. m_params.emplace_back( new PARAM<bool>( "export_idf.units_mils",
  206. &m_ExportIdf.units_mils, false ) );
  207. m_params.emplace_back( new PARAM<int>( "export_step.origin_mode",
  208. &m_ExportStep.origin_mode, 0 ) );
  209. m_params.emplace_back( new PARAM<int>( "export_step.origin_units",
  210. &m_ExportStep.origin_units, 0 ) );
  211. m_params.emplace_back( new PARAM<double>( "export_step.origin_x",
  212. &m_ExportStep.origin_x, 0 ) );
  213. m_params.emplace_back( new PARAM<double>( "export_step.origin_y",
  214. &m_ExportStep.origin_y, 0 ) );
  215. m_params.emplace_back( new PARAM<bool>( "export_step.no_virtual",
  216. &m_ExportStep.no_virtual, false ) );
  217. m_params.emplace_back( new PARAM<bool>( "export_step.replace_models",
  218. &m_ExportStep.replace_models, false ) );
  219. m_params.emplace_back( new PARAM<bool>( "export_step.overwrite_file",
  220. &m_ExportStep.overwrite_file, true ) );
  221. m_params.emplace_back( new PARAM<bool>( "export_svg.black_and_white",
  222. &m_ExportSvg.black_and_white, false ) );
  223. m_params.emplace_back( new PARAM<bool>( "export_svg.mirror",
  224. &m_ExportSvg.mirror, false ) );
  225. m_params.emplace_back( new PARAM<bool>( "export_svg.one_file",
  226. &m_ExportSvg.one_file, false ) );
  227. m_params.emplace_back(new PARAM<bool>( "export_svg.plot_board_edges",
  228. &m_ExportSvg.plot_board_edges, true ) );
  229. m_params.emplace_back( new PARAM<int>( "export_svg.page_size",
  230. &m_ExportSvg.page_size, 0 ) );
  231. m_params.emplace_back( new PARAM<wxString>( "export_svg.output_dir",
  232. &m_ExportSvg.output_dir, "" ) );
  233. m_params.emplace_back( new PARAM_LIST<int>( "export_svg.layers",
  234. &m_ExportSvg.layers, {} ) );
  235. m_params.emplace_back( new PARAM<int>( "export_vrml.units",
  236. &m_ExportVrml.units, 1 ) );
  237. m_params.emplace_back( new PARAM<bool>( "export_vrml.copy_3d_models",
  238. &m_ExportVrml.copy_3d_models, false ) );
  239. m_params.emplace_back( new PARAM<bool>( "export_vrml.use_relative_paths",
  240. &m_ExportVrml.use_relative_paths, false ) );
  241. m_params.emplace_back( new PARAM<int>( "export_vrml.ref_units",
  242. &m_ExportVrml.ref_units, 0 ) );
  243. m_params.emplace_back( new PARAM<double>( "export_vrml.ref_x",
  244. &m_ExportVrml.ref_x, 0 ) );
  245. m_params.emplace_back( new PARAM<double>( "export_vrml.ref_y",
  246. &m_ExportVrml.ref_y, 0 ) );
  247. m_params.emplace_back( new PARAM<int>( "export_vrml.origin_mode",
  248. &m_ExportVrml.origin_mode, 0 ) );
  249. m_params.emplace_back( new PARAM<int>( "zones.hatching_style",
  250. &m_Zones.hatching_style, 0 ) );
  251. m_params.emplace_back( new PARAM<int>( "zones.net_sort_mode",
  252. &m_Zones.net_sort_mode, -1 ) );
  253. m_params.emplace_back( new PARAM<double>( "zones.clearance",
  254. &m_Zones.clearance, ZONE_CLEARANCE_MIL ) );
  255. m_params.emplace_back( new PARAM<double>( "zones.min_thickness",
  256. &m_Zones.min_thickness, ZONE_THICKNESS_MIL ) );
  257. m_params.emplace_back( new PARAM<double>( "zones.thermal_relief_gap",
  258. &m_Zones.thermal_relief_gap, ZONE_THERMAL_RELIEF_GAP_MIL ) );
  259. m_params.emplace_back( new PARAM<double>( "zones.thermal_relief_copper_width",
  260. &m_Zones.thermal_relief_copper_width, ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL ) );
  261. m_params.emplace_back( new PARAM<int>( "import_graphics.layer",
  262. &m_ImportGraphics.layer, Dwgs_User ) );
  263. m_params.emplace_back( new PARAM<bool>( "import_graphics.interactive_placement",
  264. &m_ImportGraphics.interactive_placement, true ) );
  265. m_params.emplace_back( new PARAM<int>( "import_graphics.line_width_units",
  266. &m_ImportGraphics.line_width_units, 0 ) );
  267. m_params.emplace_back( new PARAM<double>( "import_graphics.line_width",
  268. &m_ImportGraphics.line_width, 0.2 ) );
  269. m_params.emplace_back( new PARAM<int>( "import_graphics.origin_units",
  270. &m_ImportGraphics.origin_units, 0 ) );
  271. m_params.emplace_back( new PARAM<double>( "import_graphics.origin_x",
  272. &m_ImportGraphics.origin_x, 0 ) );
  273. m_params.emplace_back( new PARAM<double>( "import_graphics.origin_y",
  274. &m_ImportGraphics.origin_y, 0 ) );
  275. m_params.emplace_back( new PARAM<int>( "import_graphics.dxf_units",
  276. &m_ImportGraphics.dxf_units, 0 ) );
  277. m_params.emplace_back( new PARAM<int>( "netlist.report_filter",
  278. &m_NetlistDialog.report_filter, -1 ) );
  279. m_params.emplace_back( new PARAM<bool>( "netlist.update_footprints",
  280. &m_NetlistDialog.update_footprints, true ) );
  281. m_params.emplace_back( new PARAM<bool>( "netlist.delete_shorting_tracks",
  282. &m_NetlistDialog.delete_shorting_tracks, false ) );
  283. m_params.emplace_back( new PARAM<bool>( "netlist.delete_extra_footprints",
  284. &m_NetlistDialog.delete_extra_footprints, false ) );
  285. m_params.emplace_back( new PARAM<bool>( "netlist.associate_by_ref_sch",
  286. &m_NetlistDialog.associate_by_ref_sch, false ) );
  287. m_params.emplace_back(new PARAM<int>( "place_file.units",
  288. &m_PlaceFile.units, 1 ) );
  289. m_params.emplace_back( new PARAM<int>( "place_file.file_options",
  290. &m_PlaceFile.file_options, 0 ) );
  291. m_params.emplace_back( new PARAM<int>( "place_file.file_format",
  292. &m_PlaceFile.file_format, 0 ) );
  293. m_params.emplace_back( new PARAM<bool>( "place_file.include_board_edge",
  294. &m_PlaceFile.include_board_edge, false ) );
  295. m_params.emplace_back( new PARAM<bool>( "place_file.use_place_file_origin",
  296. &m_PlaceFile.use_aux_origin, true ) );
  297. m_params.emplace_back( new PARAM<int>( "plot.all_layers_on_one_page",
  298. &m_Plot.all_layers_on_one_page, 1 ) );
  299. m_params.emplace_back( new PARAM<int>( "plot.pads_drill_mode",
  300. &m_Plot.pads_drill_mode, 2 ) );
  301. m_params.emplace_back( new PARAM<double>( "plot.fine_scale_x",
  302. &m_Plot.fine_scale_x, 0 ) );
  303. m_params.emplace_back( new PARAM<double>( "plot.fine_scale_y",
  304. &m_Plot.fine_scale_y, 0 ) );
  305. m_params.emplace_back( new PARAM<double>( "plot.ps_fine_width_adjust",
  306. &m_Plot.ps_fine_width_adjust, 0 ) );
  307. m_params.emplace_back( new PARAM<bool>( "plot.check_zones_before_plotting",
  308. &m_Plot.check_zones_before_plotting, true ) );
  309. m_params.emplace_back( new PARAM<bool>( "plot.mirror",
  310. &m_Plot.mirror, false ) );
  311. m_params.emplace_back( new PARAM<wxString>( "window.footprint_text_shown_columns",
  312. &m_FootprintTextShownColumns, "0 1 2 3 4 5 6" ) );
  313. m_params.emplace_back( new PARAM<int>( "footprint_wizard_list.width",
  314. &m_FootprintWizardList.width, -1 ) );
  315. m_params.emplace_back( new PARAM<int>( "footprint_wizard_list.height",
  316. &m_FootprintWizardList.height, -1 ) );
  317. m_params.emplace_back( new PARAM<bool>( "reannotate_dialog.annotate_sort_on_modules",
  318. &m_Reannotate.sort_on_fp_location, true ) );
  319. m_params.emplace_back( new PARAM<bool>( "reannotate_dialog.annotate_remove_front_prefix",
  320. &m_Reannotate.remove_front_prefix, false ) );
  321. m_params.emplace_back( new PARAM<bool>( "reannotate_dialog.annotate_remove_back_prefix",
  322. &m_Reannotate.remove_back_prefix, false ) );
  323. m_params.emplace_back( new PARAM<bool>( "reannotate_dialog.annotate_exclude_locked",
  324. &m_Reannotate.exclude_locked, false ) );
  325. m_params.emplace_back( new PARAM<int>( "reannotate_dialog.annotate_grid_index",
  326. &m_Reannotate.grid_index, 0 ) );
  327. m_params.emplace_back( new PARAM<int>( "reannotate_dialog.annotate_sort_code",
  328. &m_Reannotate.sort_code, 0 ) );
  329. m_params.emplace_back( new PARAM<int>( "reannotate_dialog.annotate_choice",
  330. &m_Reannotate.annotation_choice, 0 ) );
  331. m_params.emplace_back( new PARAM<int>( "reannotate_dialog.annotate_report_severity",
  332. &m_Reannotate.report_severity, 0 ) );
  333. m_params.emplace_back( new PARAM<wxString>( "reannotate_dialog.annotate_front_refdes_start",
  334. &m_Reannotate.front_refdes_start, "1" ) );
  335. m_params.emplace_back( new PARAM<wxString>( "reannotate_dialog.annotate_back_refdes_start",
  336. &m_Reannotate.back_refdes_start, "" ) );
  337. m_params.emplace_back( new PARAM<wxString>( "reannotate_dialog.annotate_front_prefix",
  338. &m_Reannotate.front_prefix, "" ) );
  339. m_params.emplace_back( new PARAM<wxString>( "reannotate_dialog.annotate_back_prefix",
  340. &m_Reannotate.back_prefix, "" ) );
  341. m_params.emplace_back( new PARAM<wxString>( "reannotate_dialog.annotate_exclude_list",
  342. &m_Reannotate.exclude_list, "" ) );
  343. m_params.emplace_back( new PARAM<wxString>( "reannotate_dialog.annotate_report_file_name",
  344. &m_Reannotate.report_file_name, "" ) );
  345. m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "action_plugins",
  346. [&]() -> nlohmann::json
  347. {
  348. nlohmann::json js = nlohmann::json::array();
  349. for( const auto& pair : m_VisibleActionPlugins )
  350. js.push_back( nlohmann::json( { { pair.first.ToUTF8(), pair.second } } ) );
  351. return js;
  352. },
  353. [&]( const nlohmann::json& aObj )
  354. {
  355. m_VisibleActionPlugins.clear();
  356. if( !aObj.is_array() )
  357. {
  358. return;
  359. }
  360. for( const auto& entry : aObj )
  361. {
  362. if( entry.empty() || !entry.is_object() )
  363. continue;
  364. for( const auto& pair : entry.items() )
  365. {
  366. m_VisibleActionPlugins.emplace_back( std::make_pair(
  367. wxString( pair.key().c_str(), wxConvUTF8 ), pair.value() ) );
  368. }
  369. }
  370. },
  371. nlohmann::json::array() ) );
  372. addParamsForWindow( &m_FootprintViewer, "footprint_viewer" );
  373. m_params.emplace_back( new PARAM<double>( "footprint_viewer.zoom",
  374. &m_FootprintViewerZoom, 1.0 ) );
  375. addParamsForWindow( &m_FootprintWizard, "footprint_wizard" );
  376. m_params.emplace_back( new PARAM<wxString>( "system.last_footprint_lib_dir",
  377. &m_lastFootprintLibDir, "" ) );
  378. m_params.emplace_back( new PARAM<wxString>( "system.last_footprint3d_dir",
  379. &m_lastFootprint3dDir, "" ) );
  380. registerMigration( 0, 1,
  381. [&]()
  382. {
  383. if( OPT<int> optval = Get<int>( "pcb_display.rotation_angle" ) )
  384. Set( "editing.rotation_angle", optval.get() );
  385. try
  386. {
  387. At( "pcb_display" ).erase( "rotation_angle" );
  388. }
  389. catch( ... )
  390. {}
  391. return true;
  392. } );
  393. }
  394. PCBNEW_SETTINGS::~PCBNEW_SETTINGS() = default;
  395. bool PCBNEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
  396. {
  397. bool ret = APP_SETTINGS_BASE::MigrateFromLegacy( aCfg );
  398. const std::string f = getLegacyFrameName();
  399. //
  400. // NOTE: there's no value in line-wrapping these; it just makes the table unreadable.
  401. //
  402. ret &= fromLegacy<bool>( aCfg, "ShowLayerManagerTools", "aui.show_layer_manager" );
  403. ret &= fromLegacy<int>( aCfg, "FootprintChooserHSashPosition", "footprint_chooser.sash_h" );
  404. ret &= fromLegacy<int>( aCfg, "FootprintChooserVSashPosition", "footprint_chooser.sash_v" );
  405. ret &= fromLegacy<int>( aCfg, "FootprintChooserWidth", "footprint_chooser.width" );
  406. ret &= fromLegacy<int>( aCfg, "FootprintChooserHeight", "footprint_chooser.height" );
  407. ret &= fromLegacy<bool>( aCfg, "FlipLeftRight", "editing.flip_left_right" );
  408. ret &= fromLegacy<bool>( aCfg, "MagneticGraphics", "editing.magnetic_graphics" );
  409. ret &= fromLegacy<int>( aCfg, "MagneticPads", "editing.magnetic_pads" );
  410. ret &= fromLegacy<int>( aCfg, "MagneticTracks", "editing.magnetic_tracks" );
  411. ret &= fromLegacy<bool>( aCfg, "DisplayPolarCoords", "editing.polar_coords" );
  412. ret &= fromLegacy<bool>( aCfg, "Use45DegreeGraphicSegments", "editing.use_45_degree_graphic_segments" );
  413. ret &= fromLegacy<bool>( aCfg, "PcbAffT", "pcb_display.graphic_items_fill" );
  414. ret &= fromLegacy<int>( aCfg, "MaxLnkS", "pcb_display.max_links_shown" );
  415. ret &= fromLegacy<bool>( aCfg, "ModAffC", "pcb_display.footprint_edge_fill" );
  416. ret &= fromLegacy<bool>( aCfg, "ModAffT", "pcb_display.footprint_text_fill" );
  417. ret &= fromLegacy<int>( aCfg, "ShowNetNamesMode", "pcb_display.net_names_mode" );
  418. ret &= fromLegacy<int>( aCfg, "PcbDisplayOrigin", "pcb_display.origin_mode" );
  419. ret &= fromLegacy<bool>( aCfg, "PcbInvertXAxis", "pcb_display.origin_invert_x_axis" );
  420. ret &= fromLegacy<bool>( aCfg, "PcbInvertYAxis", "pcb_display.origin_invert_y_axis" );
  421. ret &= fromLegacy<bool>( aCfg, "PadAffG", "pcb_display.pad_clearance" );
  422. ret &= fromLegacy<bool>( aCfg, "PadFill", "pcb_display.pad_fill" );
  423. ret &= fromLegacy<bool>( aCfg, "PadSNum", "pcb_display.pad_numbers" );
  424. ret &= fromLegacy<bool>( aCfg, "ShowRatsnestLines", "pcb_display.ratsnest_global" );
  425. ret &= fromLegacy<bool>( aCfg, "ShowRatsnestModuleLines", "pcb_display.ratsnest_footprint" );
  426. ret &= fromLegacy<bool>( aCfg, "CurvedRatsnestLines", "pcb_display.ratsnest_curved" );
  427. ret &= fromLegacy<int>( aCfg, "RotationAngle", "pcb_display.rotation_angle" );
  428. ret &= fromLegacy<int>( aCfg, "TrackDisplayClearance", "pcb_display.track_clearance_mode" );
  429. ret &= fromLegacy<bool>( aCfg, "DisplayTrackFilled", "pcb_display.track_fill" );
  430. ret &= fromLegacy<bool>( aCfg, "ViaFill", "pcb_display.via_fill" );
  431. ret &= fromLegacy<int>( aCfg, "PcbShowZonesMode", "pcb_display.zone_mode" );
  432. ret &= fromLegacy<double>( aCfg, "PlotLineWidth_mm", "plot.line_width" );
  433. aCfg->SetPath( "/dialogs/cleanup_tracks" );
  434. ret &= fromLegacy<bool>( aCfg, "DialogCleanupVias", "cleanup.cleanup_vias" );
  435. ret &= fromLegacy<bool>( aCfg, "DialogCleanupMergeSegments", "cleanup.merge_segments" );
  436. ret &= fromLegacy<bool>( aCfg, "DialogCleanupUnconnected", "cleanup.cleanup_unconnected" );
  437. ret &= fromLegacy<bool>( aCfg, "DialogCleanupShortCircuit", "cleanup.cleanup_short_circuits" );
  438. ret &= fromLegacy<bool>( aCfg, "DialogCleanupTracksInPads", "cleanup.cleanup_tracks_in_pad" );
  439. aCfg->SetPath( "../.." );
  440. ret &= fromLegacy<bool>( aCfg, "RefillZonesBeforeDrc", "drc_dialog.refill_zones" );
  441. ret &= fromLegacy<bool>( aCfg, "DrcTestFootprints", "drc_dialog.test_footprints" );
  442. ret &= fromLegacy<bool>( aCfg, "DrillMergePTHNPTH", "gen_drill.merge_pth_npth" );
  443. ret &= fromLegacy<bool>( aCfg, "DrillMinHeader", "gen_drill.minimal_header" );
  444. ret &= fromLegacy<bool>( aCfg, "DrillMirrorYOpt", "gen_drill.mirror" );
  445. ret &= fromLegacy<bool>( aCfg, "DrillUnit", "gen_drill.unit_drill_is_inch" );
  446. ret &= fromLegacy<bool>( aCfg, "OvalHolesRouteMode", "gen_drill.use_route_for_oval_holes" );
  447. ret &= fromLegacy<int>( aCfg, "DrillFileType", "gen_drill.drill_file_type" );
  448. ret &= fromLegacy<int>( aCfg, "DrillMapFileType", "gen_drill.map_file_type" );
  449. ret &= fromLegacy<int>( aCfg, "DrillZerosFormat", "gen_drill.zeros_format" );
  450. ret &= fromLegacy<bool>( aCfg, "IDFRefAutoAdj", "export_idf.auto_adjust" );
  451. ret &= fromLegacy<int>( aCfg, "IDFRefUnits", "export_idf.ref_units" );
  452. ret &= fromLegacy<double>( aCfg, "IDFRefX", "export_idf.ref_x" );
  453. ret &= fromLegacy<double>( aCfg, "IDFRefY", "export_idf.ref_y" );
  454. ret &= fromLegacy<bool>( aCfg, "IDFExportThou", "export_idf.units_mils" );
  455. ret &= fromLegacy<int>( aCfg, "STEP_Origin_Opt", "export_step.origin_mode" );
  456. ret &= fromLegacy<int>( aCfg, "STEP_UserOriginUnits", "export_step.origin_units" );
  457. ret &= fromLegacy<double>( aCfg, "STEP_UserOriginX", "export_step.origin_x" );
  458. ret &= fromLegacy<double>( aCfg, "STEP_UserOriginY", "export_step.origin_y" );
  459. ret &= fromLegacy<bool>( aCfg, "STEP_NoVirtual", "export_step.no_virtual" );
  460. ret &= fromLegacy<bool>( aCfg, "PlotSVGModeColor", "export_svg.black_and_white" );
  461. ret &= fromLegacy<bool>( aCfg, "PlotSVGModeMirror", "export_svg.mirror" );
  462. ret &= fromLegacy<bool>( aCfg, "PlotSVGModeOneFile", "export_svg.one_file" );
  463. ret &= fromLegacy<bool>( aCfg, "PlotSVGBrdEdge", "export_svg.plot_board_edges" );
  464. ret &= fromLegacy<int>( aCfg, "PlotSVGPageOpt", "export_svg.page_size" );
  465. ret &= fromLegacyString( aCfg, "PlotSVGDirectory", "export_svg.output_dir" );
  466. {
  467. nlohmann::json js = nlohmann::json::array();
  468. wxString key;
  469. bool val = false;
  470. for( unsigned i = 0; i < PCB_LAYER_ID_COUNT; ++i )
  471. {
  472. key.Printf( wxT( "PlotSVGLayer_%d" ), i );
  473. if( aCfg->Read( key, &val ) && val )
  474. js.push_back( i );
  475. }
  476. Set( "export_svg.layers", js );
  477. }
  478. {
  479. nlohmann::json js = nlohmann::json::array();
  480. wxString packed;
  481. if( aCfg->Read( "ActionPluginButtons", &packed ) )
  482. {
  483. wxStringTokenizer pluginSettingsTokenizer = wxStringTokenizer( packed, ";" );
  484. while( pluginSettingsTokenizer.HasMoreTokens() )
  485. {
  486. nlohmann::json row;
  487. wxString plugin = pluginSettingsTokenizer.GetNextToken();
  488. wxStringTokenizer pluginTokenizer = wxStringTokenizer( plugin, "=" );
  489. if( pluginTokenizer.CountTokens() != 2 )
  490. {
  491. // Bad config
  492. continue;
  493. }
  494. std::string key( pluginTokenizer.GetNextToken().ToUTF8() );
  495. bool value( pluginTokenizer.GetNextToken().Cmp( wxT( "Visible" ) ) == 0 );
  496. js.push_back( nlohmann::json( { { key, value } } ) );
  497. }
  498. }
  499. Set( "action_plugins", js );
  500. }
  501. //
  502. // NOTE: there's no value in line-wrapping these; it just makes the table unreadable.
  503. //
  504. ret &= fromLegacy<int>( aCfg, "VrmlExportUnit", "export_vrml.units" );
  505. ret &= fromLegacy<bool>( aCfg, "VrmlExportCopyFiles", "export_vrml.copy_3d_models" );
  506. ret &= fromLegacy<bool>( aCfg, "VrmlUseRelativePaths", "export_vrml.use_relative_paths" );
  507. ret &= fromLegacy<int>( aCfg, "VrmlRefUnits", "export_vrml.ref_units" );
  508. ret &= fromLegacy<double>( aCfg, "VrmlRefX", "export_vrml.ref_x" );
  509. ret &= fromLegacy<double>( aCfg, "VrmlRefY", "export_vrml.ref_y" );
  510. ret &= fromLegacy<int> ( aCfg, "VrmlOriginMode", "export_vrml.origin_mode" );
  511. ret &= fromLegacy<int>( aCfg, "Zone_Ouline_Hatch_Opt", "zones.hatching_style" );
  512. ret &= fromLegacy<int>( aCfg, "Zone_NetSort_Opt", "zones.net_sort_mode" );
  513. ret &= fromLegacy<double>( aCfg, "Zone_Clearance", "zones.clearance" );
  514. ret &= fromLegacy<double>( aCfg, "Zone_Thickness", "zones.min_thickness" );
  515. ret &= fromLegacy<double>( aCfg, "Zone_TH_Gap", "zones.thermal_relief_gap" );
  516. ret &= fromLegacy<double>( aCfg, "Zone_TH_Copper_Width", "zones.thermal_relief_copper_width" );
  517. aCfg->SetPath( "ImportGraphics" );
  518. ret &= fromLegacy<int>( aCfg, "BoardLayer", "import_graphics.layer" );
  519. ret &= fromLegacy<bool>( aCfg, "InteractivePlacement", "import_graphics.interactive_placement" );
  520. ret &= fromLegacyString( aCfg, "LastFile", "import_graphics.last_file" );
  521. ret &= fromLegacy<double>( aCfg, "LineWidth", "import_graphics.line_width" );
  522. ret &= fromLegacy<int>( aCfg, "LineWidthUnits", "import_graphics.line_width_units" );
  523. ret &= fromLegacy<int>( aCfg, "PositionUnits", "import_graphics.origin_units" );
  524. ret &= fromLegacy<double>( aCfg, "PositionX", "import_graphics.origin_x" );
  525. ret &= fromLegacy<double>( aCfg, "PositionY", "import_graphics.origin_y" );
  526. aCfg->SetPath( ".." );
  527. ret &= fromLegacy<int>( aCfg, "NetlistReportFilterMsg", "netlist.report_filter" );
  528. ret &= fromLegacy<bool>( aCfg, "NetlistUpdateFootprints", "netlist.update_footprints" );
  529. ret &= fromLegacy<bool>( aCfg, "NetlistDeleteShortingTracks", "netlist.delete_shorting_tracks" );
  530. ret &= fromLegacy<bool>( aCfg, "NetlistDeleteExtraFootprints", "netlist.delete_extra_footprints" );
  531. ret &= fromLegacy<int>( aCfg, "PlaceFileUnits", "place_file.units" );
  532. ret &= fromLegacy<int>( aCfg, "PlaceFileOpts", "place_file.file_options" );
  533. ret &= fromLegacy<int>( aCfg, "PlaceFileFormat", "place_file.file_format" );
  534. ret &= fromLegacy<bool>( aCfg, "PlaceFileIncludeBrdEdge", "place_file.include_board_edge" );
  535. ret &= fromLegacy<int>( aCfg, "PrintSinglePage", "plot.all_layers_on_one_page" );
  536. ret &= fromLegacy<int>( aCfg, "PrintPadsDrillOpt", "plot.pads_drill_mode" );
  537. ret &= fromLegacy<double>( aCfg, "PlotXFineScaleAdj", "plot.fine_scale_x" );
  538. ret &= fromLegacy<double>( aCfg, "PlotYFineScaleAdj", "plot.fine_scale_y" );
  539. ret &= fromLegacy<double>( aCfg, "PSPlotFineWidthAdj", "plot.ps_fine_width_adjust" );
  540. ret &= fromLegacy<bool>( aCfg, "CheckZonesBeforePlotting", "plot.check_zones_before_plotting" );
  541. ret &= fromLegacyString( aCfg, "FootprintTextShownColumns", "window.footprint_text_shown_columns" );
  542. ret &= fromLegacy<int>( aCfg, "FpWizardListWidth", "footprint_wizard_list.width" );
  543. ret &= fromLegacy<int>( aCfg, "FpWizardListHeight", "footprint_wizard_list.height" );
  544. migrateWindowConfig( aCfg, "ModViewFrame", "footprint_viewer" );
  545. ret &= fromLegacy<bool>( aCfg, "ModViewFrameAutoZoom", "footprint_viewer.auto_zoom" );
  546. ret &= fromLegacy<double>( aCfg, "ModViewFrameZoom", "footprint_viewer.zoom" );
  547. migrateWindowConfig( aCfg, "FootprintWizard", "footprint_wizard" );
  548. ret &= fromLegacyString( aCfg, "Fpwizard_auiPerspective", "footprint_wizard.perspective" );
  549. const std::string p = "pcbnew.InteractiveRouter.";
  550. Set( "tools.pns.meta", nlohmann::json( {
  551. { "filename", "pns" },
  552. { "version", 0 }
  553. } ) );
  554. ret &= fromLegacy<int>( aCfg, p + "Mode", "tools.pns.mode" );
  555. ret &= fromLegacy<int>( aCfg, p + "OptimizerEffort", "tools.pns.effort" );
  556. ret &= fromLegacy<bool>( aCfg, p + "RemoveLoops", "tools.pns.remove_loops" );
  557. ret &= fromLegacy<bool>( aCfg, p + "SmartPads", "tools.pns.smart_pads" );
  558. ret &= fromLegacy<bool>( aCfg, p + "ShoveVias", "tools.pns.shove_vias" );
  559. ret &= fromLegacy<bool>( aCfg, p + "StartDiagonal", "tools.pns.start_diagonal" );
  560. ret &= fromLegacy<int>( aCfg, p + "ShoveTimeLimit", "tools.pns.shove_time_limit" );
  561. ret &= fromLegacy<int>( aCfg, p + "ShoveIterationLimit", "tools.pns.shove_iteration_limit" );
  562. ret &= fromLegacy<int>( aCfg, p + "WalkaroundIterationLimit", "tools.pns.walkaround_iteration_limit" );
  563. ret &= fromLegacy<bool>( aCfg, p + "JumpOverObstacles", "tools.pns.jump_over_obstacles" );
  564. ret &= fromLegacy<bool>( aCfg, p + "SmoothDraggedSegments", "tools.pns.smooth_dragged_segments" );
  565. ret &= fromLegacy<bool>( aCfg, p + "CanViolateDRC", "tools.pns.can_violate_drc" );
  566. ret &= fromLegacy<bool>( aCfg, p + "SuggestFinish", "tools.pns.suggest_finish" );
  567. ret &= fromLegacy<bool>( aCfg, p + "FreeAngleMode", "tools.pns.free_angle_mode" );
  568. ret &= fromLegacy<bool>( aCfg, p + "InlineDragEnabled", "editing.track_drag_action" );
  569. // Initialize some new PNS settings to legacy behaviors if coming from legacy
  570. Set( "tools.pns.fix_all_segments", false );
  571. // Migrate color settings that were stored in the pcbnew config file
  572. COLOR_SETTINGS* cs = Pgm().GetSettingsManager().GetMigratedColorSettings();
  573. auto migrateLegacyColor =
  574. [&] ( const std::string& aKey, int aLayerId )
  575. {
  576. wxString str;
  577. if( aCfg->Read( aKey, &str ) )
  578. cs->SetColor( aLayerId, COLOR4D( str ) );
  579. };
  580. for( int i = 0; i < PCB_LAYER_ID_COUNT; ++i )
  581. {
  582. wxString layer = LSET::Name( PCB_LAYER_ID( i ) );
  583. migrateLegacyColor( "Color4DPCBLayer_" + layer.ToStdString(), PCB_LAYER_ID( i ) );
  584. }
  585. migrateLegacyColor( "Color4DAnchorEx", LAYER_ANCHOR );
  586. migrateLegacyColor( "Color4DAuxItems", LAYER_AUX_ITEMS );
  587. migrateLegacyColor( "Color4DGrid", LAYER_GRID );
  588. migrateLegacyColor( "Color4DNoNetPadMarker", LAYER_NO_CONNECTS );
  589. migrateLegacyColor( "Color4DNonPlatedEx", LAYER_NON_PLATEDHOLES );
  590. migrateLegacyColor( "Color4DPadThruHoleEx", LAYER_PADS_TH );
  591. migrateLegacyColor( "Color4DPCBBackground", LAYER_PCB_BACKGROUND );
  592. migrateLegacyColor( "Color4DPCBCursor", LAYER_CURSOR );
  593. migrateLegacyColor( "Color4DRatsEx", LAYER_RATSNEST );
  594. migrateLegacyColor( "Color4DTxtInvisEx", LAYER_MOD_TEXT_INVISIBLE );
  595. migrateLegacyColor( "Color4DViaBBlindEx", LAYER_VIA_BBLIND );
  596. migrateLegacyColor( "Color4DViaMicroEx", LAYER_VIA_MICROVIA );
  597. migrateLegacyColor( "Color4DViaThruEx", LAYER_VIA_THROUGH );
  598. migrateLegacyColor( "Color4DWorksheet", LAYER_DRAWINGSHEET );
  599. Pgm().GetSettingsManager().SaveColorSettings( cs, "board" );
  600. Set( "appearance.color_theme", cs->GetFilename() );
  601. double x, y;
  602. if( aCfg->Read( f + "PcbUserGrid_X", &x ) && aCfg->Read( f + "PcbUserGrid_Y", &y ) )
  603. {
  604. EDA_UNITS u = static_cast<EDA_UNITS>( aCfg->ReadLong( f + "PcbUserGrid_Unit",
  605. static_cast<long>( EDA_UNITS::INCHES ) ) );
  606. // Convert to internal units
  607. x = From_User_Unit( u, x );
  608. y = From_User_Unit( u, y );
  609. Set( "window.grid.user_grid_x", StringFromValue( u, x ) );
  610. Set( "window.grid.user_grid_y", StringFromValue( u, y ) );
  611. }
  612. // Footprint editor settings were stored in pcbnew config file. Migrate them here.
  613. auto fpedit = Pgm().GetSettingsManager().GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( false );
  614. fpedit->MigrateFromLegacy( aCfg );
  615. fpedit->Load();
  616. // Same with 3D viewer
  617. auto viewer3d = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>( false );
  618. viewer3d->MigrateFromLegacy( aCfg );
  619. viewer3d->Load();
  620. return ret;
  621. }
  622. //namespace py = pybind11;
  623. //
  624. //PYBIND11_MODULE( pcbnew, m )
  625. //{
  626. // py::class_<PCBNEW_SETTINGS>( m, "settings" )
  627. // .def_readwrite( "Use45DegreeGraphicSegments", &PCBNEW_SETTINGS::m_Use45DegreeGraphicSegments )
  628. // .def_readwrite( "FlipLeftRight", &PCBNEW_SETTINGS::m_FlipLeftRight )
  629. // .def_readwrite( "AddUnlockedPads", &PCBNEW_SETTINGS::m_AddUnlockedPads)
  630. // .def_readwrite( "UsePolarCoords", &PCBNEW_SETTINGS::m_PolarCoords)
  631. // .def_readwrite( "RotationAngle", &PCBNEW_SETTINGS::m_RotationAngle)
  632. // .def_readwrite( "ShowPageLimits", &PCBNEW_SETTINGS::m_ShowPageLimits)
  633. // ;
  634. //}